【Python】別のPCで環境を再現する:依存関係の記録と入れ直し

PythonのTopに戻る


別のPCで解析環境を作り直すなら、専用venvで依存パッケージの版を記録し、新しいvenvへ入れ直して計算を確認する。venvのフォルダーを丸ごとコピーする方法は避ける。requirements.txtは重要な記録だが、Python本体、OS、外部ライブラリ、入力データまで一式再現するファイルではない。何を記録し、どこまで確認したかを分けて残すことが大切である。

作業用の環境を先に分ける

日常的に使うPythonには、今回の解析に不要なパッケージが多数入っていることがある。その環境をそのままfreezeすると、再現に必要なものと偶然入っていたものが混ざってしまう。プロジェクト用のvenvを作り、そこで解析が動くことを確かめてから記録する。

venvは作成したPythonの版を使う。別のPCでも少なくともPythonのメジャー・マイナー版を合わせ、厳密な比較が必要ならパッチ版も記録しておく。OSやCPUが違う場合、同じ名前と版のパッケージでも利用できるwheelや内部実装が違うことがある。

依存関係と実行環境を書き出す

以下は、すでに作った.venvの依存関係を保存し、新しい.venv-rebuiltへ入れ直す書式である。Linuxで同等の手順をローカルの練習用wheelを使って確認した。macOSとWindowsは配置の違いを示すコマンド例であり、実機では実行していない。

環境の保存・再構築コマンド(実際の依存名はプロジェクトごとに異なる)

# Linux/macOS:既存環境の記録
.venv/bin/python -m pip freeze > requirements.txt
.venv/bin/python environment.py > environment.json

# Linux/macOS:同じPython版で新しい環境を作る
python3.12 -m venv .venv-rebuilt
.venv-rebuilt/bin/python -m pip install -r requirements.txt
.venv-rebuilt/bin/python -m pip check

# Windows PowerShell:同じ操作の書式
& ".\.venv\Scripts\python.exe" -m pip freeze > requirements.txt
& ".\.venv\Scripts\python.exe" environment.py > environment.json
py -3.12 -m venv .venv-rebuilt
& ".\.venv-rebuilt\Scripts\python.exe" -m pip install -r requirements.txt
& ".\.venv-rebuilt\Scripts\python.exe" -m pip check

freezeはインストール済みの状態を出力する。すべてのOS向けの解決結果を計算するロック処理ではなく、editable installやローカルパスが混ざることもある。保存したファイルを開き、別のPCに存在しない絶対パスが含まれていないかを確認したい。

environment.py

import json
import platform
import sys

print(json.dumps({
    "python": sys.version,
    "implementation": platform.python_implementation(),
    "os": platform.system(),
    "machine": platform.machine(),
}, ensure_ascii=False, indent=2))

この記録にはOSとPython本体が含まれる。さらに、再実行するスクリプトの版、必要な外部コマンド、入力データの識別情報も別に残すと後から状況を確認しやすい。個人名を含む作業パスなど、不要な情報まで公開する必要はない。

新しいvenvで入れ直すところまで確かめる

練習用のtip-demo 0.1.0をwheelから導入し、freezeした内容を新しい独立venvで読み込ませた結果が次のとおりである。例のtip-demoはこの確認用に作成したローカルパッケージで、PyPIから同名のものを探して入れる必要はない。

実行結果

requirements: tip-demo==0.1.0
pip check: No broken requirements found.
double(3): 6

導入後はpip checkだけで終わらず、実際のimportと小さな代表計算も行う。pip checkは宣言された依存条件の確認に役立つが、解析式や入力ファイル、ネイティブ拡張のすべての動作を検証するものではない。元と同じ関数が同じ入力で期待値を返すかも確かめよう。

再現の強さを必要に応じて上げる

版を==で固定すると、後日たまたま最新版が選ばれることを避けられる。それでも取得元のファイルまで固定したい場合は、ハッシュ検証やwheelの保存を検討する。依存先も含めた全ファイルを管理する必要があり、ハッシュを付けるだけで別OSへの互換性が生まれるわけではない。

ネットワークを使わず導入したい場合は、対象OS・Python版で使えるwheelを事前に集め、–no-indexと–find-linksで参照できる。今回の動作確認もその形を使った。ただし、あるPCで取得したwheelが別のCPUやOSで使えるとは限らないため、移行先の条件で確認する必要がある。

古い環境を壊す前に移行を確認する

既存のvenvへ上書きしながら直すより、新しい名前のvenvを作る方が比較しやすい。元の解析結果と新しい環境の結果を照合し、必要な確認が終わってからエディターや実行スクリプトの参照先を切り替える。古い環境を残せば、差が出たときにも調査を戻しやすい。

requirementsを保存しただけでは再現できたとはいえない。新しい環境を作る、依存を導入する、計算を実行する、結果を確認する、という一連の手順を通すことが重要である。乱数を使う処理ではシードなどの条件も、数値比較では許容誤差もあらかじめ決めておこう。

動作確認と参考資料

掲載例はLinux・CPython 3.12.14で動作確認した。OS固有のコマンドや環境ごとに変わるパスは、本文中の条件を確認して使ってほしい。

関連するTips


PythonのTopに戻る