それぞれのプロジェクトを専用のvenvに隔離し、依存関係を固定し、再現できるプロジェクト構成を採り入れましょう。
このレッスンを Kodokon で開くすべてのプロジェクトの依存関係を同じインタープリタに入れると、まっすぐバージョンの衝突へ向かいます。プロジェクトAはrequestsの2.31を必要とし、プロジェクトBは互換性のないバージョンを必要とする、といった具合です。仮想環境(venv)は、それぞれのプロジェクトを隔離します。専用のインタープリタ、専用のpip、専用のパッケージです。これは譲れないプロの作法です。ひとつのプロジェクトにひとつの環境、そしてどのマシンでも同じように作り直せること。
python -m venv .venv
source .venv/bin/activate
# On Windows:
# .venv\Scripts\activate
python -m pip install requests
python -m pip listインストールを再現できるようにするには、バージョンを固定します。pip freezeは環境全体を、推移的な依存関係も含めて、正確なバージョン付きで書き出します。再現性は最大になり、更新は骨の折れる作業になります。現代的なやり方は、この二つの必要を分けます。直接の依存関係は緩い制約とともにpyproject.tomlに宣言し、正確なインストールのためにロックファイルを生成するのです。小さなプロジェクトの規模なら、requirements.txtでまったく問題ありません。
python -m pip freeze > requirements.txt
# On another machine:
python -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt構成の面では、srcレイアウトが基準です。コードはsrc/<package>/に、テストはtests/に、設定はpyproject.tomlに置きます。srcフォルダーの意義は見た目のためではありません。カレントディレクトリからローカルのパッケージをうっかりインポートしてしまうのを防ぎます。それが起きると、パッケージングの誤りが隠れてしまうのです。テストは、実際にインストールされたパッケージに対して走ります。開発中は、pip install -e .がプロジェクトを編集可能モードでインストールしてくれます。
mkdir -p src/billing tests
touch src/billing/__init__.py
touch src/billing/invoices.py
touch tests/test_invoices.py
touch pyproject.toml README.md .gitignore
echo ".venv/" >> .gitignore