Pipenv:新しいPythonパッケージングツールのガイド
Pipenvは、pip、virtualenv、および古き良きrequirements.txtを使用して、一般的なワークフローに関連するいくつかの一般的な問題を解決するPython用のパッケージツールです。
いくつかの一般的な問題に対処することに加えて、開発プロセスを単一のコマンドラインツールに統合および簡素化します。
このガイドでは、Pipenvが解決する問題、およびPipenvでPythonの依存関係を管理する方法について説明します。 さらに、Pipenvがpackage分布の以前の方法にどのように適合するかについても説明します。
Free Bonus:Click here to get access to a free 5-day classは、Pip、PyPI、Virtualenv、要件ファイルなどのツールで一般的な依存関係管理の問題を回避する方法を示しています。
Pipenvが解決する問題
Pipenvの利点を理解するには、Pythonでのパッケージ化と依存関係管理の現在の方法を理解することが重要です。
サードパーティのパッケージを処理する一般的な状況から始めましょう。 次に、完全なPythonアプリケーションをデプロイする方法を構築します。
requirements.txtによる依存関係管理
flaskなどのサードパーティパッケージを使用するPythonプロジェクトで作業していると想像してください。 他の開発者や自動システムがアプリケーションを実行できるように、その要件を指定する必要があります。
したがって、requirements.txtファイルにflask依存関係を含めることにします。
flask
すばらしいことは、すべてがローカルで正常に機能することです。しばらくの間アプリをハッキングしてから、本番に移行することにしました。 ここが少し怖いところです…
上記のrequirements.txtファイルは、使用するflaskのバージョンを指定していません。 この場合、pip install -r requirements.txtはデフォルトで最新バージョンをインストールします。 これは、アプリケーションを壊す最新バージョンのインターフェイスまたは動作の変更がない限り問題ありません。
この例のために、flaskの新しいバージョンがリリースされたとしましょう。 ただし、開発中に使用したバージョンとの後方互換性はありません。
ここで、アプリケーションを本番環境にデプロイし、pip install -r requirements.txtを実行するとします。 Pipは、下位互換性のない最新バージョンのflaskを取得します。そのように、アプリケーションは本番環境で壊れます。
“But hey, it worked on my machine!”-私は自分でそこに行ったことがありますが、それは素晴らしい気分ではありません。
この時点で、開発中に使用したflaskのバージョンが正常に機能したことがわかります。 したがって、問題を修正するには、requirements.txtをもう少し具体的にしようとします。 version specifierをflask依存関係に追加します。 これは、pinning依存関係とも呼ばれます。
flask==0.12.1
flaskの依存関係を特定のバージョンに固定すると、pip install -r requirements.txtは、開発中に使用したflaskの正確なバージョンを設定します。 しかし、本当にそうですか?
flask自体にも依存関係があることに注意してください(pipは自動的にインストールされます)。 ただし、flask自体は、依存関係の正確なバージョンを指定していません。 たとえば、任意のバージョンのWerkzeug>=0.14を許可します。
繰り返しになりますが、この例のために、Werkzeugの新しいバージョンがリリースされたとしましょう。ただし、アプリケーションにショーストッパーのバグが発生します。
今回本番環境でpip install -r requirements.txtを実行すると、その要件を固定したため、flask==0.12.1が取得されます。 ただし、残念ながら、Werkzeugの最新のバグのあるバージョンを入手できます。 繰り返しますが、製品は生産中に壊れます。
ここでの本当の問題は、the build isn’t deterministicです。 つまり、同じ入力(requirements.txtファイル)が与えられた場合、pipは常に同じ環境を生成するとは限りません。 現時点では、本番環境の開発マシンにある正確な環境を簡単に複製することはできません。
この問題の一般的な解決策は、pip freezeを使用することです。 このコマンドを使用すると、自動的にインストールされるサブ依存関係を含む、現在インストールされているすべてのサードパーティライブラリの正確なバージョンを取得できます。 したがって、開発中のすべてを凍結して、本番環境で同じ環境を確保できます。
pip freezeを実行すると、依存関係が固定され、requirements.txtに追加できます。
click==6.7
Flask==0.12.1
itsdangerous==0.24
Jinja2==2.10
MarkupSafe==1.0
Werkzeug==0.14.1
これらの固定された依存関係により、実稼働環境にインストールされたパッケージが開発環境のパッケージと正確に一致することを保証できるため、製品が予期せず破損することはありません。 残念ながら、この「解決策」はまったく新しい問題につながります。
すべてのサードパーティパッケージの正確なバージョンを指定したので、これらのバージョンはflaskのサブ依存関係であっても、最新の状態に保つ責任があります。 パッケージメンテナがWerkzeug==0.14.2ですぐにパッチを適用したセキュリティホールがWerkzeug==0.14.1で発見された場合はどうなりますか? 以前のパッチが適用されていないバージョンのWerkzeugから発生するセキュリティの問題を回避するには、実際にWerkzeug==0.14.2に更新する必要があります。
まず、お使いのバージョンに問題があることに注意する必要があります。 次に、誰かがセキュリティホールを悪用する前に、運用環境で新しいバージョンを取得する必要があります。 したがって、新しいバージョンWerkzeug==0.14.2を指定するには、requirements.txtを手動で変更する必要があります。 この状況でわかるように、必要な更新を最新の状態に保つ責任はユーザーにあります。
真実は、コードを壊さない限り、どのバージョンのWerkzeugがインストールされるかは本当に気にしないということです。 実際に、バグ修正、セキュリティパッチ、新機能、最適化などを確実に取得するために、おそらく最新バージョンが必要になります。
本当の質問は:“How do you allow for deterministic builds for your Python project without gaining the responsibility of updating versions of sub-dependencies?”
ネタバレ注意:簡単な答えはPipenvを使用することです。
異なる依存関係を持つプロジェクトの開発
ギアを少し変えて、複数のプロジェクトで作業しているときに発生する別の一般的な問題について話しましょう。 ProjectAにはdjango==1.9が必要であるが、ProjectBにはdjango==1.10が必要であると想像してください。
デフォルトでは、Pythonはすべてのサードパーティパッケージをシステム全体の場所に保存しようとします。 つまり、ProjectAとProjectBを切り替えるたびに、正しいバージョンのdjangoがインストールされていることを確認する必要があります。 これにより、各プロジェクトの要件を満たすためにパッケージをアンインストールおよび再インストールする必要があるため、プロジェクト間の切り替えが困難になります。
標準的な解決策は、独自のPython実行可能ファイルとサードパーティのパッケージストレージを持つvirtual environmentを使用することです。 このようにして、ProjectAとProjectBは適切に分離されます。 同じパッケージ保管場所を共有していないため、プロジェクトを簡単に切り替えることができます。 PackageAは、独自の環境で必要なバージョンのdjangoを使用でき、PackageBは、必要なバージョンを完全に分離して使用できます。 このための非常に一般的なツールは、virtualenv(またはPython 3ではvenv)です。
Pipenvには仮想環境管理が組み込まれているため、パッケージ管理用の単一のツールを使用できます。
依存関係の解決
依存関係の解決とはどういう意味ですか? 次のようなrequirements.txtファイルがあるとします。
package_a
package_b
package_aにサブ依存関係package_cがあり、package_aにはこのパッケージの特定のバージョンpackage_c>=1.0が必要であるとします。 同様に、package_bには同じサブ依存関係がありますが、package_c<=2.0が必要です。
理想的には、package_aとpackage_bをインストールしようとすると、インストールツールはpackage_c(>=1.0と<=2.0)の要件を調べて、それらの要件を満たすバージョン。 プログラムが最終的に機能するように、ツールが依存関係を解決することを願っています。 これが、「依存関係の解決」という意味です。
残念ながら、現時点ではpip自体に実際の依存関係の解決策はありませんが、それをサポートするopen issueがあります。
pipが上記のシナリオを処理する方法は次のとおりです。
-
package_aをインストールし、最初の要件(package_c>=1.0)を満たすバージョンのpackage_cを探します。 -
次に、Pipはその要件を満たすために最新バージョンの
package_cをインストールします。package_cの最新バージョンが3.1であるとしましょう。
これがトラブルの(潜在的な)始まりです。
pipによって選択されたpackage_cのバージョンが将来の要件(package_c<=2.0を必要とするpackage_bなど)に適合しない場合、インストールは失敗します。
この問題の「解決策」は、requirements.txtファイルでサブ依存関係(package_c)に必要な範囲を指定することです。 そのようにして、pipはこの競合を解決し、それらの要件を満たすパッケージをインストールできます。
package_c>=1.0,<=2.0
package_a
package_b
ただし、以前と同じように、サブ依存関係(package_c)に直接関心があります。 これに関する問題は、package_aが知らないうちに要件を変更すると、指定した要件(package_c>=1.0,<=2.0)が受け入れられなくなり、インストールが失敗する可能性があることです…。 本当の問題は、サブ依存関係の要件を最新の状態に保つ責任があることです。
理想的には、インストールツールは、サブ依存バージョンを明示的に指定しなくても、すべての要件を満たすパッケージをインストールするのに十分なほどスマートです。
Pipenvの概要
問題に対処したので、Pipenvがどのようにそれらを解決するかを見てみましょう。
まず、インストールしましょう:
$ pip install pipenv
これを実行すると、Pipenvは基本的に代替として機能するため、pipを事実上忘れることができます。 また、Pipfile(requirements.txtを置き換えることを意味します)とPipfile.lock(決定論的ビルドを可能にする)の2つの新しいファイルを導入します。
Pipenvは、内部でpipとvirtualenvを使用しますが、単一のコマンドラインインターフェイスでそれらの使用法を簡素化します。
使用例
素晴らしいPythonアプリケーションの作成から始めましょう。 まず、仮想環境でシェルを生成して、このアプリの開発を分離します。
$ pipenv shell
これにより、仮想環境がまだ存在しない場合に作成されます。 Pipenvは、すべての仮想環境をデフォルトの場所に作成します。 Pipenvのデフォルトの動作を変更する場合は、いくつかのenvironmental variables for configurationがあります。
引数--twoと--threeをそれぞれ使用して、Python2または3環境の作成を強制できます。 それ以外の場合、Pipenvはデフォルトのvirtualenvが検出したものを使用します。
補足:Pythonのより具体的なバージョンが必要な場合は、必要なバージョンで
--python引数を指定できます。 例:--python 3.6
これで、必要なサードパーティパッケージflaskをインストールできます。 ああ、でも最新バージョンではなくバージョン0.12.1が必要なことはわかっているので、具体的に説明してください。
$ pipenv install flask==0.12.1
端末に次のようなものが表示されるはずです。
Adding flask==0.12.1 to Pipfile's [packages]...
Pipfile.lock not found, creating...
PipfileとPipfile.lockの2つのファイルが作成されていることがわかります。 これらについてはすぐに詳しく見ていきます。 別のサードパーティパッケージnumpyをインストールして、数を減らしましょう。 特定のバージョンは必要ないので、指定しないでください。
$ pipenv install numpy
バージョン管理システム(VCS)から何かを直接インストールしたい場合は、できます! pipを使用する場合と同様に、場所を指定します。 たとえば、バージョン管理からrequestsライブラリをインストールするには、次の手順を実行します。
$ pipenv install -e git+https://github.com/requests/requests.git#egg=requests
インストールを編集可能にするには、上記の-e引数に注意してください。 現在、Pipenvがサブ依存関係を解決するためのthis is required。
この素晴らしいアプリケーションの単体テストもいくつかあり、それらを実行するためにpytestを使用したいとします。 本番環境ではpytestは必要ないため、この依存関係を--dev引数を使用して開発専用に指定できます。
$ pipenv install pytest --dev
--dev引数を指定すると、依存関係がPipfileの特別な[dev-packages]の場所に配置されます。 これらの開発パッケージは、--dev引数をpipenv installで指定した場合にのみインストールされます。
異なるセクションでは、開発にのみ必要な依存関係と、ベースコードが実際に機能するために必要な依存関係を分けています。 通常、これはdev-requirements.txtやtest-requirements.txtなどの追加の要件ファイルを使用して実現されます。 これで、すべてが異なるセクションの下の単一のPipfileに統合されます。
さて、ローカル開発環境ですべてが動作し、本番環境にプッシュする準備ができたとしましょう。 そのためには、本番環境で同じ環境を使用できるように環境をロックする必要があります。
$ pipenv lock
これにより、Pipfile.lockが作成/更新されます。これは、手動で編集する必要はありません(また、編集することも意図されていません)。 常に生成されたファイルを使用する必要があります。
ここで、本番環境でコードとPipfile.lockを取得したら、最後に成功した環境をインストールする必要があります。
$ pipenv install --ignore-pipfile
これにより、Pipenvは、インストールにPipfileを無視し、Pipfile.lockに含まれるものを使用するように指示されます。 このPipfile.lockを指定すると、Pipenvは、pipenv lock、サブ依存関係などを実行したときとまったく同じ環境を作成します。
ロックファイルは、環境内のパッケージのすべてのバージョンのスナップショットを作成することにより、確定的なビルドを可能にします(pip freezeの結果と同様)。
ここで、別の開発者がコードにいくつかの追加を行いたいとします。 この状況では、Pipfileを含むコードを取得し、次のコマンドを使用します。
$ pipenv install --dev
これにより、開発に必要なすべての依存関係がインストールされます。これには、通常の依存関係と、install中に--dev引数で指定した依存関係の両方が含まれます。
正確なバージョンがPipfileで指定されていない場合、
installコマンドは、依存関係(およびサブ依存関係)がバージョンを更新する機会を提供します。
これは、前述の問題の一部を解決するため、重要な注意事項です。 例として、依存関係の1つの新しいバージョンが利用可能になったとします。 この依存関係の特定のバージョンは必要ないため、Pipfileで正確なバージョンを指定する必要はありません。 pipenv installを実行すると、新しいバージョンの依存関係が開発環境にインストールされます。
ここで、コードを変更し、いくつかのテストを実行して、すべてが期待どおりに機能していることを確認します。 (ユニットテストはありますか?)これで、前と同じように、pipenv lockで環境をロックすると、新しいバージョンの依存関係で更新されたPipfile.lockが生成されます。 前と同じように、ロックファイルを使用して、この新しい環境を運用環境で複製できます。
このシナリオからわかるように、開発環境と運用環境が同じであることを保証するために本当に必要としない正確なバージョンを強制する必要はなくなりました。 また、「気にしない」サブ依存関係の更新を常に把握する必要はありません。 Pipenvを使用したこのワークフローは、優れたテストと組み合わされ、すべての依存関係管理を手動で行う問題を修正します。
Pipenvの依存関係解決アプローチ
Pipenvは、コア依存関係のすべての要件を満たすサブ依存関係のインストールを試みます。 ただし、競合する依存関係がある場合(package_aにはpackage_c>=1.0が必要ですが、package_bにはpackage_c<1.0が必要です)、Pipenvはロックファイルを作成できず、次のようなエラーを出力します以下:
Warning: Your dependencies could not be resolved. You likely have a mismatch in your sub-dependencies. You can use $ pipenv install --skip-lock to bypass this mechanism, then run $ pipenv graph to inspect the situation. Could not find a version that matches package_c>=1.0,package_c<1.0
警告にあるように、トップレベルの依存関係とそのサブ依存関係を理解するために、依存関係グラフを表示することもできます。
$ pipenv graph
このコマンドは、依存関係を示すツリーのような構造を出力します。 例を示しましょう。
Flask==0.12.1
- click [required: >=2.0, installed: 6.7]
- itsdangerous [required: >=0.21, installed: 0.24]
- Jinja2 [required: >=2.4, installed: 2.10]
- MarkupSafe [required: >=0.23, installed: 1.0]
- Werkzeug [required: >=0.7, installed: 0.14.1]
numpy==1.14.1
pytest==3.4.1
- attrs [required: >=17.2.0, installed: 17.4.0]
- funcsigs [required: Any, installed: 1.0.2]
- pluggy [required: <0.7,>=0.5, installed: 0.6.0]
- py [required: >=1.5.0, installed: 1.5.2]
- setuptools [required: Any, installed: 38.5.1]
- six [required: >=1.10.0, installed: 1.11.0]
requests==2.18.4
- certifi [required: >=2017.4.17, installed: 2018.1.18]
- chardet [required: >=3.0.2,<3.1.0, installed: 3.0.4]
- idna [required: >=2.5,<2.7, installed: 2.6]
- urllib3 [required: <1.23,>=1.21.1, installed: 1.22]
pipenv graphの出力から、以前にインストールした最上位の依存関係(Flask、numpy、pytest、およびrequests)とその下を確認できます。あなたは彼らが依存しているパッケージを見ることができます。
さらに、ツリーを逆にして、それを必要とする親のサブ依存関係を表示できます。
$ pipenv graph --reverse
この逆ツリーは、競合するサブ依存関係を把握しようとする場合により便利です。
Pipfile
Pipfileはrequirements.txtを置き換えることを意図しています。 Pipenvは現在、Pipfileを使用するためのリファレンス実装です。 pip itself will be able to handle these filesである可能性が非常に高いようです。 また、Pipenv is even the official package management tool recommended by Python itselfも注目に値します。
Pipfileの構文はTOMLであり、ファイルはセクションに分割されています。 開発専用パッケージの場合は[dev-packages]、最小限必要なパッケージの場合は[packages]、Pythonの特定のバージョンなどの他の要件の場合は[requires]。 以下のサンプルファイルを参照してください。
[[source]]
url = "https://pypi.python.org/simple"
verify_ssl = true
name = "pypi"
[dev-packages]
pytest = "*"
[packages]
flask = "==0.12.1"
numpy = "*"
requests = {git = "https://github.com/requests/requests.git", editable = true}
[requires]
python_version = "3.6"
理想的には、Pipfileにサブ依存関係がないようにする必要があります。 つまり、実際にインポートして使用するパッケージのみを含める必要があります。 requestsのサブ依存関係であるという理由だけで、chardetをPipfileに保持する必要はありません。 (Pipenvは自動的にインストールします。)Pipfileは、パッケージに必要な最上位の依存関係を伝える必要があります。
Pipfile.lock
このファイルは、環境を再現するための正確な要件を指定することにより、確定的なビルドを可能にします。 より安全な検証をサポートするためのパッケージとハッシュの正確なバージョンが含まれています。これもpip itself now supportsです。 サンプルファイルは次のようになります。 このファイルの構文はJSONであり、ファイルの一部を...で除外していることに注意してください。
{
"_meta": {
...
},
"default": {
"flask": {
"hashes": [
"sha256:6c3130c8927109a08225993e4e503de4ac4f2678678ae211b33b519c622a7242",
"sha256:9dce4b6bfbb5b062181d3f7da8f727ff70c1156cbb4024351eafd426deb5fb88"
],
"version": "==0.12.1"
},
"requests": {
"editable": true,
"git": "https://github.com/requests/requests.git",
"ref": "4ea09e49f7d518d365e7c6f7ff6ed9ca70d6ec2e"
},
"werkzeug": {
"hashes": [
"sha256:d5da73735293558eb1651ee2fddc4d0dedcfa06538b8813a2e20011583c9e49b",
"sha256:c3fd7a7d41976d9f44db327260e263132466836cef6f91512889ed60ad26557c"
],
"version": "==0.14.1"
}
...
},
"develop": {
"pytest": {
"hashes": [
"sha256:8970e25181e15ab14ae895599a0a0e0ade7d1f1c4c8ca1072ce16f25526a184d",
"sha256:9ddcb879c8cc859d2540204b5399011f842e5e8823674bf429f70ada281b3cc6"
],
"version": "==3.4.1"
},
...
}
}
すべての依存関係に指定された正確なバージョンに注意してください。 Pipfileにないwerkzeugのようなサブ依存関係でさえ、このPipfile.lockに表示されます。 ハッシュは、開発時と同じパッケージを取得するために使用されます。
このファイルを手動で変更しないでください。 これは、pipenv lockで生成されることを意図しています。
Pipenvの追加機能
次のコマンドを使用して、デフォルトのエディターでサードパーティのパッケージを開きます。
$ pipenv open flask
これにより、デフォルトのエディターでflaskパッケージが開きます。または、EDITOR環境変数を使用してプログラムを指定することもできます。 たとえば、Sublime Textを使用しているので、EDITOR=sublを設定するだけです。 これにより、使用しているパッケージの内部を掘り下げることが非常に簡単になります。
シェルを起動せずに、仮想環境でコマンドを実行できます。
$ pipenv run
ご使用の環境のセキュリティの脆弱性(およびPEP 508の要件)を確認してください。
$ pipenv check
次に、パッケージが不要になったとします。 アンインストールできます:
$ pipenv uninstall numpy
さらに、仮想環境からインストール済みのすべてのパッケージを完全に消去するとします。
$ pipenv uninstall --all
--allを--all-devに置き換えて、開発パッケージを削除することができます。
Pipenvは、.envファイルが最上位ディレクトリに存在する場合の環境変数の自動ロードをサポートしています。 そうすれば、pipenv shellを使用して仮想環境を開くと、ファイルから環境変数が読み込まれます。 .envファイルには、キーと値のペアのみが含まれています。
SOME_ENV_CONFIG=some_value
SOME_OTHER_ENV_CONFIG=some_other_value
最後に、ここにあるものを見つけるための簡単なコマンドがあります。 仮想環境の場所を確認する方法:
$ pipenv --venv
プロジェクトのホームの場所を確認する方法:
$ pipenv --where
パッケージ配布
コードをパッケージとして配布する場合は、このすべてがどのように機能するかを尋ねるかもしれません。
はい、コードをパッケージとして配布する必要があります
Pipenvはsetup.pyファイルでどのように機能しますか?
その質問には多くのニュアンスがあります。 まず、ビルド/配布システムとしてsetuptoolsを使用している場合は、setup.pyファイルが必要です。 これはしばらくの間デファクトスタンダードでしたが、recent changesはsetuptoolsの使用をオプションにしました。
これは、flitのようなプロジェクトが新しいpyproject.tomlを使用して、setup.pyを必要としない別のビルドシステムを指定できることを意味します。
そうは言っても、近い将来、setuptoolsとそれに付随するsetup.pyは、多くの人にとってデフォルトの選択肢になるでしょう。
パッケージを配布する方法としてsetup.pyを使用する場合の推奨ワークフローは次のとおりです。
-
setup.py -
install_requiresキーワードには、パッケージ“minimally needs to run correctly.”を含める必要があります -
Pipfile -
パッケージの具体的な要件を表します
-
Pipenvを使用してパッケージをインストールすることにより、
setup.pyから最小限必要な依存関係を引き出します。-
pipenv install '-e .'を使用する -
これにより、
Pipfileに"e1839a8" = {path = ".", editable = true}のような行が作成されます。
-
-
Pipfile.lock -
pipenv lockから生成された再現可能な環境の詳細
明確にするために、最小要件をpipenv installで直接ではなく、setup.pyで入力します。 次に、pipenv install '-e .'コマンドを使用して、パッケージを編集可能としてインストールします。 これにより、すべての要件がsetup.pyから環境に取り込まれます。 次に、pipenv lockを使用して、再現可能な環境を取得できます。
コードをパッケージとして配布する必要はありません
すばらしいです! 配布またはインストールすることを目的としていないアプリケーション(個人のWebサイト、デスクトップアプリケーション、ゲームなど)を開発している場合、実際にはsetup.pyは必要ありません。
この状況では、Pipfile /Pipfile.lockコンボを使用して、前述のフローで依存関係を管理し、本番環境に再現可能な環境をデプロイできます。
私はすでにrequirements.txtを持っています。 Pipfileに変換するにはどうすればよいですか?
pipenv installを実行すると、requirements.txtが自動的に検出され、Pipfileに変換され、次のように出力されます。
requirements.txt found, instead of Pipfile! Converting… Warning: Your Pipfile now contains pinned versions, if your requirements.txt did. We recommend updating your Pipfile to specify the "*" version, instead.
上記の警告に注意してください。
requirements.txtファイルに正確なバージョンを固定している場合は、本当に必要な正確なバージョンのみを指定するようにPipfileを変更することをお勧めします。 これにより、移行の本当のメリットを得ることができます。 たとえば、次のものがあるが、numpyの正確なバージョンは実際には必要ないとします。
[packages]
numpy = "==1.14.1"
依存関係に特定のバージョン要件がない場合は、ワイルドカード文字*を使用して、任意のバージョンをインストールできることをPipenvに通知できます。
[packages]
numpy = "*"
*を含むバージョンを許可することに不安を感じる場合は、通常、既に使用しているバージョン以上を指定して、新しいバージョンを引き続き利用できるようにすることをお勧めします。
[packages]
numpy = ">=1.14.1"
もちろん、新しいリリースを常に最新の状態に保つには、パッケージが変更されたときにコードが期待どおりに機能することを保証する責任があります。 これは、コードの機能リリースを保証する場合、このPipenvフロー全体にテストスイートが不可欠であることを意味します。
パッケージの更新、テストの実行、すべてのパスの確認、環境のロックを許可すると、重大な変更が導入されていないことを簡単に知ることができます。 依存関係が原因で問題が発生した場合は、いくつかの回帰テストを記述し、依存関係のバージョンにさらに制限を加える可能性があります。
たとえば、pipenv installの実行後にnumpy==1.15がインストールされ、コードが破損した場合、開発中またはテスト中に気付くと思いますが、いくつかのオプションがあります。
-
依存関係の新しいバージョンで機能するようにコードを更新します。
以前のバージョンの依存関係との下位互換性が不可能な場合は、必要なバージョンを
Pipfileに追加する必要もあります。[packages] numpy = ">=1.15" -
Pipfileの依存関係のバージョンを<に制限して、コードを壊したばかりのバージョンにします。[packages] numpy = ">=1.14.1,<1.15"
オプション1は、コードが最新の依存関係を使用していることを保証するため、推奨されます。 ただし、オプション2の方が時間がかからず、コードの変更は不要で、依存関係の制限のみが必要です。
pipが取るのと同じ-r引数を持つ要件ファイルからインストールすることもできます。
$ pipenv install -r requirements.txt
dev-requirements.txtなどがある場合は、それらをPipfileに追加することもできます。 --dev引数を追加するだけで、正しいセクションに配置されます。
$ pipenv install -r dev-requirements.txt --dev
さらに、別の方法で、Pipfileから要件ファイルを生成できます。
$ pipenv lock -r > requirements.txt
$ pipenv lock -r -d > dev-requirements.txt
次は何ですか?
Pythonエコシステムの自然な進歩は、パッケージインデックス(PyPIなど)からパッケージを取得してビルドするときに、Pipfileを使用して最小限必要な依存関係をインストールするビルドシステムであるように思われます。 Pipfile design specificationはまだ開発中であり、Pipenvは単なるリファレンス実装であることに再度注意することが重要です。
そうは言っても、setup.pyのinstall_requiresセクションが存在せず、代わりに最小要件としてPipfileが参照される未来を見ることができました。 または、setup.pyが完全になくなり、メタデータやその他の情報を別の方法で取得し、Pipfileを使用して必要な依存関係を取得します。
Pipenvはチェックアウトする価値がありますか?
絶対に。 すでに使用しているツール(pipとvirtualenv)を単一のインターフェースに統合する方法と同じですが。 ただし、それだけではありません。 Pipfileを追加すると、本当に必要な依存関係のみを指定できます。
開発環境を複製できるようにするためだけに、すべてのバージョンを自分で管理するという頭痛の種がなくなりました。 Pipfile.lockを使用すると、どこにいても環境を正確に再現できるため、安心して開発できます。
これらすべてに加えて、Pipfile形式が採用され、pipなどの公式Pythonツールでサポートされる可能性が非常に高いため、ゲームを先取りすることは有益です。 ああ、すべてのコードをPython 3にも更新していることを確認してください:2020 is coming up fast。
参照、さらに読む、興味深い議論など
Free Bonus:Click here to get access to a free 5-day classは、Pip、PyPI、Virtualenv、要件ファイルなどのツールで一般的な依存関係管理の問題を回避する方法を示しています。