2019/03/27

Python Tips: pip でパッケージの開発版を利用したい

pip で Python パッケージの開発版を利用する方法についてです。

ここで「パッケージ」というのは、コマンド pip (または python3 -m pip )でインストールできる distribution packages (配布パッケージ)のことを指しています。

また、「開発版」というのは、バージョンがまだ付けられていない最新のコードという意味です。例えば、この記事を書いてる時点で Django の最新バージョンは 2.1.7 ですが、開発版はそこからおよそ 50 〜 100 コミット進んでいます。

早速結論ですが、次のように pip install コマンドの引数を git+[リポジトリの URL] とすれば OK です。

$ pip install git+[リポジトリの URL]

例えば Django の場合だとリポジトリが GitHub にあるので次のようにします。

$ pip install git+https://github.com/django/django.git

本記事執筆時に確認したかぎりは、 GitHub の場合は末尾の .git を省略することもできます。

$ pip install git+https://github.com/django/django

特定のリビジョンのコードを使いたい場合は、次のように末尾に @[コミットハッシュ] を追加すれば OK です。一意に特定できれば、ハッシュはすべて指定しなくてもよいようです。

$ # https://github.com/django/django/commit/d26b2424437dabeeca94d7900b37d2df4410da0c を利用する
$ pip install git+https://github.com/django/django@d26b2424437

@~ は、コミットハッシュの他にもタグやブランチで指定したい場合にも使用することができます。

コードをビルドせずにそのまま利用したい場合は editable mode の -e オプションを併用します。ただし、 editable mode を使用する場合は、次のように末尾に #egg=[パッケージ名] で名前を指定してやる必要があります。指定しなかった場合はその旨のエラーメッセージが表示されるだけでコマンドが終了します。

$ pip install -e git+https://github.com/django/django.git#egg=django

開発版を入れたパッケージをアンインストールしたいときは、通常の場合と同じように単純にパッケージ名を指定すれば OK です。

$ pip uninstall django

以上です。

昨今 VCS といえば Git で、私が実際に利用しているのは Git だけなのでここで Git を例にあげましたが、 Git の他にも Mercurial ・ Bazaar ・ Subversion がサポートされているとのこと。私は試していませんが、それぞれプリフィックスは次のとおりです。

  • Mercurial: hg+
  • Bazaar: bzr+
  • Subversion: svn+

実際に Git 以外の VCS を利用したいときは PyPI のドキュメント を確認してから利用するようにしてください。

ちなみに、 pip + venv なパッケージ管理ツール Poetry の場合は、専用の --git というオプションが用意されており、次のような形で開発版を利用できるようになっています。 pip よりも少しわかりやすいですね。

$ poetry add --git=https://github.com/django/django django

ちなみに --git オプションを使ってインストールされたパッケージは pyproject.toml 内で次のように表現されます(動作確認は Poetry 0.12.11 で行いました)。

django = {git = "https://github.com/django/django"}

というわけで pip でパッケージの開発版を利用する方法についてでした。

参考

2019/03/25

Python Tips:出力を一時的に無効化したい

バタバタしていて前回から間が空いてしまいました。

今回は Python のコードの中で出力を一時的に無効化したい(捨てたい)ときの方法についてです。

早速結論ですが、まさにそのために用意されている os.devnull を利用します。

Python の公式ドキュメントによると、 os.devnull は POSIX 準拠の OS では /dev/null を、 Windows では nul を指すとのこと。

この os.devnullcontextlib.redirect_stdout を組み合わせれば、対象の関数やメソッドの中身に手を加えることなく、一時的に出力を無効化することができます:

import os
from contextlib import redirect_stdout

def func_with_stdout():
    print('通常だとこれは標準出力に出力されます。')


# `通常だとこれは標準出力に出力されます。` は出力されない
with redirect_stdout(open(os.devnull, 'w')):
    func_with_stdout()

個人的には、自動テストの中でこのようなことをしたくなることがときどきあります。定形のイディオムとして覚えておくと便利です。

参考