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()

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

参考

2018/12/12

ライブラリ: Poetry

今回は Python のパッケージ「 Poetry 」を紹介します。



最初に「 Poetry とは何ぞや」( WHAT )の部分を説明した後に「 Poetry の使い方」( HOW )について説明します。最後に「 Pipenv からの移行方法」についてかんたんに説明します。

Poetry とは


Poetry とは 2018 年 2 月頃から開発がスタートした Python パッケージの管理ツールです。


pipvenv を組み合わせて、 npmbundlecomposer 等他の言語で定番のパッケージ管理ツールと似た使用感で使える Python パッケージ管理機能を提供しています。私自身はまだアプリケーションでしか使ったことがありませんが、アプリケーションでも配布用のパッケージでも使えるとのことです。

Pipenv をご存知の方には「 Pipenv の代替物」という説明の方がわかりやすいかもしれません。


Pipenv は当初大きな期待を持って迎えられましたが(私も期待しましたが)、さまざまな問題が出ており最近はどうも先行きが怪しい感じです。私自身 Pipenv の導入によって便利になったところがある一方で Pipenv を使っていなかったら抱えていなかった新たなストレスも増えた感じがします。 Poetry は私のような「脱 Pipenv 」を検討している方にとって有力な移行先候補のひとつです。

Poetry の使い方


ここでは Poetry のバージョン 0.12.10 における使い方を説明します。

尚、私は Poetry をアプリケーションのプロジェクトにしか使っていない(配布パッケージのプロジェクトには使っていない)ので、配布パッケージの依存を管理するための情報はまったくカバーできていません。また、 Poetry のバージョンが進むと使い方が変わると思いますので、参考にされる際はそのあたりににご注意ください。

インストール

公式に推奨されているインストール方法は、専用のスクリプト get-poetry.py を使ったものです。

$ curl -sSL https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py | python

異なるバージョンの Python が同居している環境では、適切な python コマンドを選択する必要があります。

$ curl -sSL https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py | python3.7

このコマンドを実際に実行すると私の場合は次のようなメッセージが出ました。

$ curl -sSL https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py | python
Retrieving Poetry metadata

# Welcome to Poetry!

This will download and install the latest version of Poetry,
a dependency and package manager for Python.

It will add the `poetry` command to Poetry's bin directory, located at:

$HOME/.poetry/bin

This path will then be added to your `PATH` environment variable by
modifying the profile files located at:

$HOME/.profile
$HOME/.bash_profile

You can uninstall at any time with `poetry self:uninstall`,
or by executing this script with the --uninstall option,
and these changes will be reverted.

Installing version: 0.12.10
  - Downloading poetry-0.12.10-darwin.tar.gz (7.12MB)

Poetry (0.12.10) is installed now. Great!

To get started you need Poetry's bin directory ($HOME/.poetry/bin) in your `PATH`
environment variable. Next time you log in this will be done
automatically.

To configure your current shell run `source $HOME/.poetry/env`

スクリプトの実行が成功すると、 Unix 系の OS なら $HOME/.poetry/bin に実行可能な poetry ファイルが置かれます。このディレクトリを環境変数 PATH に追加しておくと、その後はフルパスを指定しなくても poetry コマンドが実行できるようになります(ちなみに、私の環境では get-poetry.pyPATH に追加するコードを ~/.bash_profile に自動的に追加しました)。

~/.bashrc:
# for Python/Poetry
export PATH="$HOME/.poetry/bin:$PATH"

PATH の追加が終わったら poetry コマンドが使用できるようになっているはずです。例えば次のようにして正しく実行できればインストールは完了です。

$ poetry --version
Poetry 0.12.10

アンインストール

Poetry そのものをアンインストールしたくなったときは、インストールのときと同じ get-poetry.py スクリプトが使えます。

公式のドキュメントには、次のように get-poetry.py をいったんダウンロードしてから実行する方法が紹介されています。

$ python get-poetry.py --uninstall

get-poetry.py をファイルとして保存せずに直接実行する次のような方法も利用可能です。

$ curl -sSL https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py | POETRY_UNINSTALL=1 python

自動補完の設定

サブコマンドの自動補完のための設定も公式に用意されています。

例えば、 Bash の場合は次のコマンドの出力を ~/.bash_profile 等に追加しておけば次回 ~/.bash_profile を読み込んだ後は自動補完が有効になります。

$ poetry completions bash

1. プロジェクトを作成する

Poetry を実際に利用し始めるときに最初に行うべきことはプロジェクトの作成です。プロジェクトを作成するときに使えるコマンドには次の 2 つがあります。

  • poetry init
  • poetry new

poetry init はインタラクティブな入力 UI を提供した後入力内容に沿って pyproject.toml ファイルを生成します。入力項目はおおよそ次のとおりです。

  • Package name
  • Version
  • Description
  • Author
  • License
  • Compatible Python versions

生成されるファイル pyproject.toml は、ちょうど npm における package.json と同等の役割を果たすファイルです。

他方の poetry newpyproject.toml を含む、パッケージの雛形(ファイル一式)を生成します。

パッケージをゼロから作成する場合には poetry new が使えますが、おそらくほとんどのプロジェクトでは poetry init から始めることになるかと思います。

2. パッケージを追加する

poetry init 等でプロジェクトを作成したら、パッケージを追加します。パッケージの追加には poetry add を使用します。

$ poetry add flask

引数にはパッケージ名を指定します。パッケージ名は複数指定することもできます。

$ poetry add flask peewee gunicorn

開発用でパッケージを追加したいときは --dev オプションを使用します。

$ poetry add --dev pytest

ちなみに、パッケージの extras を追加したい場合は --extras オプションを使用します。

# pip なら
pip install django-anymail[mailgun]

# poetry なら
poetry add django-anymail --extras mailgun

3. パッケージをインストールする

poetry add で追加されたパッケージをインストールするには poetry install を使用します。

$ poetry install

パッケージはグローバルにではなく Poetry が管理する virtualenv の中にインストールされます。指定されたパッケージの依存パッケージも含めて、すべてのパッケージ情報は poetry.lock に保存されます。同じパッケージ環境を複数の環境で共有したい場合は poetry.lock を Git に登録するとよいかと思います。

ちなみに、私が実行したかぎりでは、 Poetry が現在のプロジェクトに対して用意している virtualenv の場所は poetry shellpoetry debug:info コマンドで確認することができました。

4. パッケージを表示する

利用パッケージとして登録されているパッケージを確認するときは poetry show を使用します。

$ poetry show

poetry show コマンドはさまざまなオプションを受け付けます。例えば、更新可能なパッケージを確認したい場合は --outdated オプションが使えます。

$ poetry show --outdated

5. パッケージを利用する

Poetry がインストールしたパッケージは Poetry がプロジェクト単位で用意した virtualenv 内にインストールされています。そのため、パッケージを利用したいときには専用のコマンドを使用します。利用できるコマンドは次の 2 つです。

  • poetry run
  • poetry shell

poetry run は、一コマンド単位で virtualenv を有効化して実行したいときに使用します。コマンドが終了したら対象の virtualenv を自動的に deactivate してくれます。

$ poetry run コマンド
$ # 例
$ poetry run python manage.py runserver

poetry shell は、対象の virtualenv を有効化します。 poetry run は対象コマンドを実行後に即 virtualenv から脱出しますが、 poetry shell は明示的に exit しないかぎり virtualenv が有効になったままとなります。

$ poetry shell
$ # virtualenv 内で実行したいコマンドを実行する
$ # ...
$ exit

6. パッケージ更新

すでに登録されているパッケージを更新するときは poetry update コマンドを使用します。

$ poetry update flask

原則、指定されたパッケージのみが更新されるようです。 Pipenv とは異なり直感的な動作をしてくれます。

7. パッケージ削除

登録されているパッケージを削除するときは poetry remove を使用します。

$ poetry remove flask

アプリケーションの依存パッケージの管理についてはおおよそ以上のコマンドを覚えておけば十分ではないかと思います。

私自身まだ実用する機会がありませんが、アプリケーションではなく配布パッケージ管理のためのコマンドとして次のもの等が用意されています。配布パッケージの管理に Poetry を利用したい方はこれらもチェックされてみるとよいでしょう。

  • poetry build
  • poetry publish

その他代表的なコマンドとして以下のコマンド等も用意されています。

  • poetry list サブコマンドの一覧を表示
  • poetry cache:clear poetry のキャッシュ(?)を削除
  • poetry self:update poetry 自身を更新
  • poetry help ヘルプを表示

このあたりは公式のドキュメントは poetry list で確認することもできるので、丸覚えしなくても必要に応じて確認すればよいのではないかと個人的には思います。

Pipenv からの乗り換え


おそらく Poetry を使い始める理由として多いのは Pipenv からの乗り換えでしょう。ここでは私の経験を踏まえて Pipenv からの乗り換えに際して必要な作業をかんたんにご紹介します。

1. Poetry をインストール

上の手順のとおりに Poetry 本体をインストールします。

2. Poetry プロジェクトを作成

Pipenv から Poetry に切り替えたいプロジェクトのディレクトリに移動し、 poetry init を実行します。

$ poetry init

各入力項目に適宜回答したら pyproject.toml ファイルが作成されます。

3. Pipfile から pyproject.toml への移行

Pipfile の中身を確認しながら、パッケージと開発用パッケージをすべて poetry add で追加します。

$ poetry add 利用パッケージの一覧
$ poetry add --dev 開発用パッケージの一覧

通常の利用パッケージと開発用のパッケージは別々に登録します。

4. スクリプトのコマンドを書き換え

Makefilefabfile.py の中に pipenv run 等のコマンドがあればそれらを poetry run に変更します。主要なコマンドはおおよそ次のとおりに書き換えるとよいでしょう。

  • pipenv runpoetry run
  • pipenv installpoetry install
  • pipenv shellpoetry shell
  • pipenv updatepoetry update

以上です。複雑なことをやっていなければ Pipenv から Poetry への移行は高々数ステップで問題なく行えるのではないかと思います。

おわりに


というわけで、 Python のパッケージ管理ツール Poetry の使い方についてでした。 Pipenv と同様まだできてから日の浅いツールなのでこの先どのようになるかはわかりません。ただ、導入の学習コストは少なく Pipenv のような非直感的なふるまいも特に見られない感じなので、興味のある方は気軽に試してみてよいのではないかと思います。

Poetry についてより詳しく知りたい方は公式のドキュメントをご覧になってみてください。


次の日本語の記事もとてもわかりやすくておすすめです。各サブコマンドのオプションや関連する PEP ( Python Enhancement Proposals )等にも言及されています。


Pipenv の問題点とそれにまつわる議論については次のページ等が参考になります。興味のある方は読んでみてください。


追記 2018/12/25:

配布パッケージのプロジェクトで Poetry を使う方法については次の記事でとても丁寧に説明されています。興味のある方はご覧になってみてください。