今日は作成した仮想環境が古くなった場合に一度にアップデートする方法をまとめておきます。
更新があるライブラリを取得しアップデート
結論から記載すると下記コマンドで一斉アップデートできます。
# 更新があるライブラリを取得しアップデートする
python3 -m pip list --outdated --format=freeze | grep -v '^\[' | cut -d = -f 1 | grep . | xargs -L1 -n1 python3 -m pip install -U
長々としたコマンドになってしまっているのでそれぞれの処理の役割も実行結果を載せておきます。
Macbookで実行しましたが、Linuxでも動作すると思います。
> 22/11/6追記 pip22.3.1以降対応 (22.3.1を含む)
ERROR: List format 'freeze' can not be used with the --outdated option エラーが出る方は上記コマンドは使えません。
どうやらpip22.3.1になってから--outdatedと--format=freezeは一緒に使えなくなったようです。詳細のチケット
python3 -m pip list --outdated --format=json | python3 -m json.tool | grep name | sed -e 's/"//g' | sed -e 's/ //g' | sed -e 's/,//g' | cut -d : -f 2 | xargs -L1 -n1 python3 -m pip install -U
--outdated --format=jsonだと動作するようなので対応しました。
下記のようなエラーが出てくる場合があります。requestsがcharset-normalizer<3,>=2を必要としているのに対して最新のcharset-normalizerは3.0.0をインストールしてしまって依存関係が解決できない問題のようです。
Collecting charset-normalizer
Downloading charset_normalizer-3.0.0-cp38-cp38-macosx_10_9_x86_64.whl (122 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 122.1/122.1 kB 1.9 MB/s eta 0:00:00
Installing collected packages: charset-normalizer
Attempting uninstall: charset-normalizer
Found existing installation: charset-normalizer 2.1.1
Uninstalling charset-normalizer-2.1.1:
Successfully uninstalled charset-normalizer-2.1.1
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
requests 2.28.1 requires charset-normalizer<3,>=2, but you have charset-normalizer 3.0.0 which is incompatible.
Successfully installed charset-normalizer-3.0.0
仮想環境のバックアップは事前に取得しておき、アップデートコマンド実行後は最終的にpip checkコマンドで依存関係に問題がないが確認した方が良さそうです。
今回の場合だとjupyterlabをアップデートしたときにcharset-normalizerが2.11のものが入ってくれたようで問題ありませんでした。
Installing collected packages: charset-normalizer, jupyterlab
Attempting uninstall: charset-normalizer
Found existing installation: charset-normalizer 3.0.0
Uninstalling charset-normalizer-3.0.0:
Successfully uninstalled charset-normalizer-3.0.0
Attempting uninstall: jupyterlab
Found existing installation: jupyterlab 3.4.8
Uninstalling jupyterlab-3.4.8:
Successfully uninstalled jupyterlab-3.4.8
Successfully installed charset-normalizer-2.1.1 jupyterlab-3.5.0
python3 -m pip check
No broken requirements found.
依存関係のエラーが出た場合の対応方法
もしアップデート中に依存関係のエラーが出た場合、どう対応するかまとめてみました。
とりあえず一旦依存関係のエラーを出します。
Installing collected packages: charset-normalizer
Attempting uninstall: charset-normalizer
Found existing installation: charset-normalizer 2.1.1
Uninstalling charset-normalizer-2.1.1:
Successfully uninstalled charset-normalizer-2.1.1
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
requests 2.28.1 requires charset-normalizer<3,>=2, but you have charset-normalizer 3.0.0 which is incompatible.
Successfully installed charset-normalizer-3.0.0
はい、アップデートしたらcharset-normalizer 3.0.0 which is incompatibleエラーが出ました。
python3 -m pip check
requests 2.28.1 has requirement charset-normalizer<3,>=2, but you have charset-normalizer 3.0.0.
requestsライブラリはcharset-normalizer<3,>=2が必要なようです。そのためcharset-normalizerのバージョン2をインストールすれば解決しそうです。
# charset-normalizer2以上3より前のバージョンをインストール
python3 -m pip install "charset-normalizer<3,>=2"
Collecting charset-normalizer<3,>=2
Using cached charset_normalizer-2.1.1-py3-none-any.whl (39 kB)
Installing collected packages: charset-normalizer
Attempting uninstall: charset-normalizer
Found existing installation: charset-normalizer 3.0.0
Uninstalling charset-normalizer-3.0.0:
Successfully uninstalled charset-normalizer-3.0.0
Successfully installed charset-normalizer-2.1.1
charset-normalizer-2.1.1がインストールされました。
python3 -m pip check
No broken requirements found.
依存関係も問題なし!
コマンドの詳細 (pip22.3.1より前)
(pip22.3.1より前) python3 -m pip list --outdated --format=freeze
# 新しいバージョンが存在するライブラリの一覧を取得
python3 -m pip list --outdated --format=freeze
asttokens==2.0.5 debugpy==1.6.0 executing==0.8.3 ipykernel==6.13.0 jupyter-client==7.3.1 jupyter-core==4.10.0 matplotlib-inline==0.1.3 numpy==1.19.0 pip==22.1.2 prompt-toolkit==3.0.29 Pygments==2.12.0 pyzmq==23.1.0 qtconsole==5.3.1 setuptools==41.2.0 stack-data==0.2.0 tornado==6.1 traitlets==5.2.2.post1 [notice] A new release of pip available: 22.1.2 -> 22.2.2 [notice] To update, run: pip install --upgrade pip
(pip22.3.1より前) grep -v '^['
# [ から始まる行を除外する処理を追加
python3 -m pip list --outdated --format=freeze | grep -v '^\['
asttokens==2.0.5 debugpy==1.6.0 executing==0.8.3 ipykernel==6.13.0 jupyter-client==7.3.1 jupyter-core==4.10.0 matplotlib-inline==0.1.3 numpy==1.19.0 pip==22.1.2 prompt-toolkit==3.0.29 Pygments==2.12.0 pyzmq==23.1.0 qtconsole==5.3.1 setuptools==41.2.0 stack-data==0.2.0 tornado==6.1 traitlets==5.2.2.post1
(pip22.3.1より前) cut -d = -f 1
# 「=」というキャラクタで文字列を分割し分割された一番最初の文字列を返却する処理を追加
python3 -m pip list --outdated --format=freeze | grep -v '^\[' | cut -d = -f 1
asttokens debugpy executing ipykernel jupyter-client jupyter-core matplotlib-inline numpy pip prompt-toolkit Pygments pyzmq qtconsole setuptools stack-data tornado traitlets
(pip22.3.1より前) grep .
# 何かしらの文字が存在する行のみ抽出する処理を追加 (空行は除外)
python3 -m pip list --outdated --format=freeze | grep -v '^\[' | cut -d = -f 1 | grep .
asttokens debugpy executing ipykernel jupyter-client jupyter-core matplotlib-inline numpy pip prompt-toolkit Pygments pyzmq qtconsole setuptools stack-data tornado traitlets
(pip22.3.1より前) xargs -L1 -n1 python3 -m pip install -U
# 各行の文字列を引数としてpython3 -m pip install -U を実行する処理を追加
python3 -m pip list --outdated --format=freeze | grep -v '^\[' | cut -d = -f 1 | grep . | xargs -L1 -n1 python3 -m pip install -U
Requirement already satisfied: asttokens in ./other1/lib/python3.8/site-packages (2.0.5)
Collecting asttokens
Using cached asttokens-2.0.8-py2.py3-none-any.whl (23 kB)
Requirement already satisfied: six in ./other1/lib/python3.8/site-packages (from asttokens) (1.16.0)
Installing collected packages: asttokens
Attempting uninstall: asttokens
Found existing installation: asttokens 2.0.5
Uninstalling asttokens-2.0.5:
Successfully uninstalled asttokens-2.0.5
Successfully installed asttokens-2.0.8
・・・省略・・・
Collecting traitlets
Using cached traitlets-5.3.0-py3-none-any.whl (106 kB)
Installing collected packages: traitlets
Attempting uninstall: traitlets
Found existing installation: traitlets 5.2.2.post1
Uninstalling traitlets-5.2.2.post1:
Successfully uninstalled traitlets-5.2.2.post1
Successfully installed traitlets-5.3.0
無事すべての更新可能なライブラリをアップデート出来ました。
依存関係のチェック
# アップデート後に不整合が起きていないか念のためチェック
python3 -m pip check
No broken requirements found.
大丈夫みたいです。
参考
・https://www.activestate.com/resources/quick-reads/how-to-update-all-python-packages/
・https://stackoverflow.com/questions/1611809/remove-empty-lines-in-a-text-file-via-grep

