ここ最近Pythonのローカル開発環境においては、Poetryで仮想環境+パッケージ管理を行い、direnvで環境変数管理を行うスタンスなのですが、VS Code上でDebug実行しようと思ったら少し設定が必要だったのでメモ的に残しておきます。
Poetry
Poetryは仮想環境構築とパッケージ管理をまとめて実行できる便利なツールです。つまり、venvとpipの代替ツールとなります。詳細は以前記事を書いたのでそちらを参照ください。
poetryでパッケージ・仮想環境を管理
direnv
12 factor を意識して、設定は環境変数に格納するというのが一般的になってきていると思いますが、ターミナルであるディレクトリにcd
したさいに、現在のディレクトリもしくは親ディレクトリを探索して、.envrc
が存在していた場合そこに記載されている内容を環境変数にロードしてくれる便利なツールです。別のディレクトリに移動した際は、環境変数はアンロードされます。
インストール
macユーザであればhomebrewで入れるのが一番楽だと思います。その他のインストール方法はこちらを参照ください。
brew install direnv
次にシェルにフックします。Bashの場合は.bashrc
に以下のように記載します。その他のシェルの方はこちらを参照ください。
eval "$(direnv hook bash)"
これでdirenvがシェルで有効になりました。
設定
任意のディレクトリに.envrc
を作成して、設定したい環境変数を記載していきます。
export PROJECT_DIR=/hoge/fuga
export PROJECT_ID=fuga
export PYTHONPATH="${PROJECT_DIR}:${PYTHONPATH}"
ファイルを作成すると、以下のように.envrc
がブロックされているというエラーが出ますので、
direnv: error /hoge/fuga/.envrc is blocked. Run `direnv allow` to approve its content
direnv allow
コマンドでブロックを解除してあげます。以後.envrc
の内容を変更するたびにdirenv allow
を行う必要があります。
direnv allow
direnv: loading /hoge/fuga/.envrc
direnv: export +PROJECT_DIR +PROJECT_ID +PYTHONPATH
これにより、この例ではPROJECT_DIR
PROJECT_ID
PYTHONPATH
が環境変数に格納されました。
以後は、シェルでこの/hoge/fuga
ディレクトリ配下にcd
しただけで自動的に.envrc
に記載されている内容が環境変数に格納されるようになります。
VS CodeでDebug実行
通常のPython Debug環境準備
まず、VS CodeのExtensionsアイコンからPythonプラグインをインストールします。
次に、VS CodeのDebugアイコンからDebug画面を開き、Add Configration...
をクリックし、Python File
を選択すると、テンプレートのlaunch.json
が作成されます。
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
}
]
}
この状態で任意のpythonファイルを開いて、Start Debugging
アイコンをクリックするかF5
でDebugをスタートすることができます。
ただし、設定によっては以下のエラーが発生することがあります。その場合は個別に対応が必要です。
- PoetryでインストールしたパッケージがModuleNotFoundErrorになる
- direnvで設定したはずの環境変数が参照できない
PoetryでインストールしたパッケージがModuleNotFoundErrorになるケースの対処
PoetryでインストールしたパッケージがModuleNotFoundErrorになるのは、Poetryの仮想環境をVS Codeが認識できてないためです。そのため、認識させてあげればOKです。
一つ目の方法は、.vscode/settings.json
にPoetryの仮想環境のpythonのpathを直接指定する方法です。
pathはpoetry env info
で確認して、
poetry env info
> Virtualenv
> Python: 3.9.0
> Implementation: CPython
> Path: /Users/xxxxx/Library/Caches/pypoetry/virtualenvs/myproject-xxxxxxx-py3.9
> Valid: True
.vscode/settings.json
にpythonpathとしてそのpathを記載します。
{
"python.pythonPath": "/Users/xxxxx/Library/Caches/pypoetry/virtualenvs/myproject-xxxxxxx-py3.9"
}
二つ目の方法は、プロジェクト内に仮想環境を作ってしまう方法です。
poetry config virtualenvs.in-project true # --localオプションをつけると設定範囲をプロジェクト内に限定
poetry env remove myproject-xxxxxxx-py3.9 # すでに仮想環境を作ってしまっている場合のみ
poetry env use python # 仮想環境を構築
VS CodeのPythonのDebuggerは賢くて、プロジェクト内にvenvの仮想環境がある場合はその仮想環境をactivateしてくれるため、Poetryでインストールしたパッケージもちゃんと認識してされます。
source /Users/xxxxx/workplace/myproject.venv/bin/activate
direnvで設定したはずの環境変数が参照できないケースの対処
VS CodeのDebug実行で起動されるシェルはログインシェルではないため、.bash_profile
は読み込まれません。direnvはフックをシェルに登録することで環境変数格納を実行するのですが、このフックの登録を.bash_profile
で行っていると、Debug実行時に環境変数が読み込まれないという問題が発生します。
こちらも対処方法を紹介します。
一つ目は、direnvのフックの処理をちゃんと.bashrc
に記載するという対応です。基本はこれで対応すべきです。
二つ目は、direnvを経由せずにDebug実行時に直接環境変数を取り込む方法です。
direnvは.envrc
に以下のようにdotenv
とだけ書いておくと.env
ファイルの内容を見に行くようになります。
dotenv
.env
ファイルには、KEY=VALUE
の形式で環境変数を記載することができます。
PROJECT_DIR=/hoge/fuga
PROJECT_ID=fuga
PYTHONPATH="${PROJECT_DIR}:${PYTHONPATH}"
そして、上記.env
は、launch.json
に以下のように設定しておくことで、Debug実行時に環境変数として読み込まれます。
{
"configurations": [
{
"envFile": "${workspaceFolder}/.env",
}
]
}
一つ目の対応は当然やるとして、個人的には二つ目の対応もやることにしました。今後Docker上で実行したくなった時とかに、.env
の形式であればそのまま使いまわせるためです。
その他Tips
パッケージ内のコードもDebug
デフォルトだと自分プロジェクト内のコードしかDebugすることができないのですが、launch.json
に以下の設定を行うことで、パッケージ内のコードもDebugすることができるようになります。
{
"configurations": [
{
"justMyCode": false,
}
]
}