はじめに
先日、Pythonライブラリのバージョンアップに取り組みました。
その際、pipコマンドを使って、あれこれ作業をしたので、その内容をまとめました。
目次
下準備
こちらの下準備をしていただければ、以下の内容をハンズオンできます。
内容のみ確認したい方は飛ばしてください。
virtualenvで検証環境を作成
検証用の環境をvirtualenvを使って準備します。
virtualenvが入っていない方は以下のコマンドでインストールしてください。
$ pip install virtualenv
それでは、検証用環境を作成します。
環境適用後、コマンドラインの先頭に(${環境名})
と表示されていればOKです。
(私の場合は(pip_test)
)
# pip_testという名前でPython3.11の環境を作成する
$ virtualenv -p python3.11 pip_test
# pip_testをカレントディレクトリに適用する
$ source pip_test/bin/activate
source pip_test/bin/activate
でpip_testが有効化されるのは、このセッション限りです。
永続化したい場合は「pyenvを利用」「.bashrcで設定」などをしてみてください。
ライブラリをインストール
検証用にrequestsをインストールしてみます。
まずはバージョンアップ前ということで適当な古いバージョンを指定します。
$ pip install requests==2.27.1
これで下準備は完了です!
インストールされているライブラリの確認
現在のリストをpip freeze
を利用してrequirements.txtに出力します。
$ pip freeze > requirements.txt
certifi==2023.11.17
charset-normalizer==2.0.12
idna==3.6
requests==2.27.1
urllib3==1.26.18
先ほどインストールしたrequests以外にもライブラリが入っています。
これらは依存関係により、インストールされたライブラリたちです。
ちなみに依存関係はpip show
で確認することができます。
$ pip show requests
Name: requests
Version: 2.27.1
Summary: Python HTTP for Humans.
Home-page: https://requests.readthedocs.io
Author: Kenneth Reitz
Author-email: me@kennethreitz.org
License: Apache 2.0
Location: xxxxxxxxxxxxxxxx
Requires: certifi, charset-normalizer, idna, urllib3
Required-by:
Requiresがrequestsが利用するライブラリ、Required-byがrequestsを利用するライブラリです。
旧バージョンの削除
現在インストールされているライブラリを削除してから、新たにバージョンアップ後のライブラリをインストールするという流れで進めていきます。
(他にも方法がありそうですが。。。)
先ほど出力したrequirements.txtを利用して、ライブラリを削除します。
-y
オプションは、削除のたびに確認されるのが面倒なので付けています。
$ pip uninstall -y -r requirements.txt
念のため、キャッシュも削除しておきます。
$ pip cache purge
不要かもしれないので、ここは任意で。
キャッシュ周りでエラーが発生することもあるようなので、削除しています。
バージョンアップ
全てのライブラリを最新バージョンに上げる場合
requirements.txtから以下のようにバージョンを削除し、pip install -r requirements.txt
を実行することで可能です。
certifi
charset-normalizer
idna
requests
urllib3
特定のライブラリのみバージョンを指定したい場合
「脆弱性が見つかった」など、至急で特定のライブラリのみに対応するケースを想定しています。
今回はurllib3のバージョンを1.26.18
から2.1.0
に上げる場合を試してみます。
requirements.txtを以下のように編集して、pip install -r requirements.txt
を実行します。
certifi==2023.11.17
charset-normalizer==2.0.12
idna==3.6
requests==2.27.1
- urllib3==1.26.18
+ urllib3==2.1.0
実は、この状態だと次のようなエラーが発生します。
$ pip install -r requirements.txt
Collecting certifi==2023.11.17 (from -r requirements.txt (line 1))
Using cached certifi-2023.11.17-py3-none-any.whl.metadata (2.2 kB)
Collecting charset-normalizer==2.0.12 (from -r requirements.txt (line 2))
Using cached charset_normalizer-2.0.12-py3-none-any.whl (39 kB)
Collecting idna==3.6 (from -r requirements.txt (line 3))
Using cached idna-3.6-py3-none-any.whl.metadata (9.9 kB)
Collecting requests==2.27.1 (from -r requirements.txt (line 4))
Downloading requests-2.27.1-py2.py3-none-any.whl (63 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 63.1/63.1 kB 1.5 MB/s eta 0:00:00
Collecting urllib3==2.1.0 (from -r requirements.txt (line 5))
Using cached urllib3-2.1.0-py3-none-any.whl.metadata (6.4 kB)
INFO: pip is looking at multiple versions of requests to determine which version is compatible with other requirements. This could take a while.
ERROR: Cannot install -r requirements.txt (line 4) and urllib3==2.1.0 because these package versions have conflicting dependencies.
The conflict is caused by:
The user requested urllib3==2.1.0
requests 2.27.1 depends on urllib3<1.27 and >=1.21.1
To fix this you could try to:
1. loosen the range of package versions you've specified
2. remove package versions to allow pip attempt to solve the dependency conflict
ERROR: ResolutionImpossible: for help visit https://pip.pypa.io/en/latest/topics/dependency-resolution/#dealing-with-dependency-conflicts
これはrequestsの2.27.1が、urllib3の1.21.1以上、1.27未満でなければ利用できないため、発生したエラーです。
このような場合、依存関係にあるライブラリについてもバージョンアップできるかどうか、個別に調査し、判断する必要があります。
requestsのバージョンを上げても問題なさそうであれば、以下のようにバージョンを上げてやれば、無事インストールできます。
(バージョンを指定せずに、最新バージョンをインストールすることも可能です。)
certifi==2023.11.17
charset-normalizer==2.0.12
idna==3.6
- requests==2.27.1
+ requests==2.31.0
urllib3==2.1.0
バージョンアップは以上です。
あとは、各プロジェクトで行なっている動作検証をして、問題なければ完了です!