Pythonでpip管理のパッケージを全て最新版にアップデート
今までPythonのpipでインストールしたモジュールは全て手動で管理していたが、OSを新しくインストールしてから面倒くさくなった。
確かに手動で管理して置かなければどのバージョンを使っているのか理解せずに使ってしまうが、とりあえず全て最新版としておけば全ての環境で共通したバージョンを使えることに成るので問題ない。
特定のバージョンを使いたいときはvirtualenvなんかで管理するだろうし、とりあえず標準バージョンは全て最新版にしておいたほうがいいだろうと今さらながらに気がついた。
そして調べてみるとなかなか方法が見つからなかったのでメモとして残しておく。誰かが同じように最新版にしておこうと考えだすことを祈って。
Python言語によるプログラミングイントロダクション: 世界標準MIT教科書
- 作者: ジョン・V.グッターグ,John V. Guttag,久保幹雄
- 出版社/メーカー: 近代科学社
- 発売日: 2014/12/29
- メディア: 単行本
- この商品を含むブログ (3件) を見る
====
自前で全て最新版にアップデートするにはfreezeオプションからバージョンを解析してアップデートをかければいいのだけど、コレをするまでもなく便利なそのまんまのパッケージがあった。
$ sudo pip3 install pip-tools # python2では'sudo pip install pip-tools'
これでPythonのパッケージ管理ツールでパッケージを管理するツールが入れられる。素晴らしい。
使い方は簡単で
$ pip-review
とすれば新しいバージョンがあるパッケージを教えてくれる。
そして全てアップデートする場合は
$ sudo pip-review --auto
とすれば自動で全てアップデートされるとのこと。
だが自動はやはり怖いので、手動で確認しながらアップデートする方が良い。
$ sudo pip-review --interactive
で確認し持ってアップデートを行える。
ちなみに私の環境(ubuntu14.04 amd64 Python3.4(pip3))ではうまく動かない。(多分Python2.7環境では動く)
% sudo pip-review
/bin/sh: 1: pip: not found
Traceback (most recent call last):
File "/usr/local/bin/pip-review", line 275, in
main()
File "/usr/local/bin/pip-review", line 235, in main
installed = list(get_installed_pkgs(local=args.local))
File "/usr/local/bin/pip-review", line 141, in get_installed_pkgs
output = check_output(command).decode('utf-8')
File "/usr/lib/python3.4/subprocess.py", line 616, in check_output
raise CalledProcessError(retcode, process.args, output=output)
subprocess.CalledProcessError: Command 'pip freeze' returned non-zero exit status 127
われらがUbuntuLinux14.04ではPython2.7とPython3.4がデフォルトでインストールされており、aptから「python3-pip」パッケージとして「pip3(Python2.7ならpip)」コマンドをインストールすることになる。
なのでpip-reviewコマンドが前提としているpipコマンドはなく、pip3コマンドしか無い。なのでそのエラーが出ている。
pip-reviewコマンドにはpipコマンド名を渡す引数はないようだし、私はPython2.7を使っていないので無理やり変更する。これは推奨される方法ではないだろうし、pip-reviewパッケージ自体が更新されたら改めて修正する必要があるかと思う。
pip-reviewコマンドは以下のパスにインストールされている。
$ which pip-review
/usr/local/bin/pip-review
なのでemacsなんかで開いて修正する。
$ sudo emacs /usr/local/bin/pip-review
# 手元のバージョンでは
# 137行目 command = 'pip freeze'
# 211行目 os.system('pip install {0}=={1}'.format(pkg, version))
# の"pip"を"pip3"に変更する
これで上記のコマンドが実行できるようになりパッケージを最新版に出来た。
ちなみに、何のパッケージかわからないものや、いくつか現在のバージョンのほうが新しいものがあったりしたのでそれは無視しておいた。
だが途中でエラーが出て失敗するようになり、更には次回からpip-review自体もエラーが出るようになった。
$ pip-review
Traceback (most recent call last):
File "/usr/bin/pip3", line 9, in
load_entry_point('pip==1.5.4', 'console_scripts', 'pip3')()
File "/usr/lib/python3/dist-packages/pkg_resources.py", line 351, in load_entry_point
return get_distribution(dist).load_entry_point(group, name)
File "/usr/lib/python3/dist-packages/pkg_resources.py", line 2363, in load_entry_point
return ep.load()
File "/usr/lib/python3/dist-packages/pkg_resources.py", line 2088, in load
entry = __import__(self.module_name, globals(),globals(), ['__name__'])
File "/usr/lib/python3/dist-packages/pip/__init__.py", line 11, in
from pip.vcs import git, mercurial, subversion, bazaar # noqa
File "/usr/lib/python3/dist-packages/pip/vcs/mercurial.py", line 9, in
from pip.download import path_to_url
File "/usr/lib/python3/dist-packages/pip/download.py", line 25, in
from requests.compat import IncompleteRead
ImportError: cannot import name 'IncompleteRead'
Traceback (most recent call last):
File "/usr/local/bin/pip-review", line 275, in
main()
File "/usr/local/bin/pip-review", line 235, in main
installed = list(get_installed_pkgs(local=args.local))
File "/usr/local/bin/pip-review", line 141, in get_installed_pkgs
output = check_output(command).decode('utf-8')
File "/usr/lib/python3.4/subprocess.py", line 616, in check_output
raise CalledProcessError(retcode, process.args, output=output)
subprocess.CalledProcessError: Command 'pip3 freeze' returned non-zero exit stat
これはpipのバージョンが古くて依存関係やらで問題が出ている様子。ちなみにこのpip-reviewではpip自体のアップデートはされないので別にアップデートする必要がある。
$ sudo easy_install3 -U pip
これでpip3自体が最新版になる。コレをしてからpip-reviewするほうがいい。そしてもっと言えばaptからpipを入れるんじゃなくて自前で入れたほうがいいかと思う。そうしなければaptで管理されているバージョンと食い違ってしまう。
そんなこんなでこれで最新版にすることが出来る。