オープンソースこねこね

Webプログラミングなどについてあれこれ。

Pythonの開発環境

MacPythonの開発環境を構築したかったので少しばかり調査、試行錯誤しました。調査メモと現時点で落とし所になった構成のまとめ。

調査

モダンなpython開発環境は

  • python: ランタイム本体
  • pip: パッケージの管理コマンド(rubyのgem的な役割)
  • virtualenv: パッケージをディレクトリ単位で管理する仮想環境(rubyのbundler的な役割)
  • pyenv: 複数バージョンのpythonを管理(rbenvとかphpenvとかと同様)
  • pyenv-virtualenv: pyenvでvirtualenvの仮想環境を作成、管理するプラグイン

などが使われる模様。情報ソースは以下のサイトなどなど。

以下のオペレーションを実際にやってみました。

  • pyenvを使ってpythonをインストール
  • virtualenvで仮想環境を構築
  • pyenv-virtualenvで仮想環境を構築

所感。

  • 複数バージョンのpythonは今のところ私には必要ない。pyenvはなくていい。
  • 現状、やりたいことは、開発するときにプロジェクトディレクトリ配下にリソースをまとめたい。グローバルを汚染したくない、ということ。
  • virtualenvディレクトリに入ってからsource bin/activateしないと有効にならない。また出るときはdeactivateが必要。地味にめんどい。
  • pyenv-virtualenvでpyenv管理の仮想環境を作ってpyenv localでローカルの設定をしておけば、ディレクトリ移動で仮想環境が有効になるが、仮想環境自体が~/.pyenv配下に保存されて、インストールパッケージがプロジェクトのディレクトリ配下に配置されない。

いまひとつ不満が解消されないまま、さらに調べていたらいつも使っているdirenvが組み込みの関数でpythonのvirtualenvを構築、ロードに対応していることを発見。

https://github.com/direnv/direnv/blob/c2cfad5ee664fed68224c44fd0549e73615f6b79/stdlib.sh#L352

試してみたらいい感じだったので、現状これとhomebrewでインストールできるpythonを使う構成に落ち着きました。以下、その環境の詳細となります。

環境構築

最終的な構成は以下になります。

  • python (version2.x)
  • pip
  • virtualenv
  • direnv

インストール手順。まずはpythonをインストールMac標準のよりバージョンが新しくpipもバンドルされてるのでhomebrewで提供されているものを使います。direnvもhomebrewでインストールする。

$ brew install python
$ brew install direnv

virtualenvはpipでシステムにインストール

$ pip install virtualenv

システムにインストールするものは以上です。

開発環境の使い方

プロジェクトディレクトリの作成

何か開発したいときはプロジェクトディレクトリを作成して、

$ mkdir python_project
$ cd python_project

layout_pythonを記述した.envrcファイルを用意する。

$ echo "layout_python" > .envrc && direnv allow

すると

direnv: loading .envrc                                                                                                            
Running virtualenv with interpreter /usr/local/bin/python
New python executable in /path/to/python_project/.direnv/python-2.7.12/bin/python2.7
Also creating executable in /path/to/python_project/.direnv/python-2.7.12/bin/python
Installing setuptools, pip, wheel...done.
direnv: export +VIRTUAL_ENV ~PATH

となってpython_project/.direnvにvirtualenvの仮想環境が構築された上に、VIRTUAL_ENV環境変数が設定され仮想環境が有効になります。 (source bin/activateしたのと同様の状態になる)

パッケージのインストール

試しにpipでこの仮想環境にインストール済みのパッケージを確認してみます。

$ pip list
pip (8.1.2)
setuptools (27.2.0)
wheel (0.30.0a0)

そこに新しくパッケージをインストールします。

$ pip install supervisor

もう一度pip listすると

$ pip list
meld3 (1.0.2)
pip (8.1.2)
setuptools (27.2.0)
supervisor (3.3.1)
wheel (0.30.0a0)

supervisorがインストールできていることが確認できます。そしてこのプロジェクトディレクトリから出て、グローバルでのパッケージを確認すると

$ cd ..
$ pip list
mercurial (3.9.1)
pip (8.1.2)
setuptools (23.1.0)
vboxapi (1.0)
virtualenv (15.0.3)
wheel (0.29.0)

プロジェクトでインストールしたものが入っていないことが確認にできます。再びプロジェクトディレクトリに入ると、仮想環境が有効になり、インストール済みパッケージももとに戻ります。

パッケージの書き出しと復元

pip freezeでプロジェクトにインストールしたパッケージを書き出しておき、

$ pip freeze > requirements.txt

.direnvを削除して、仮想環境を消去し、一度プロジェクトディレクトリを出ます。この状態でもう一度プロジェクトディレクトリに入ると

$ rm -rf .direnv 
$ cd ..
$ cd python_project
direnv: loading .envrc                                                                                                            
Running virtualenv with interpreter /usr/local/bin/python
New python executable in /path/to/python_project/.direnv/python-2.7.12/bin/python2.7
Also creating executable in /path/to/python_project/.direnv/python-2.7.12/bin/python
Installing setuptools, pip, wheel...done.
direnv: export +VIRTUAL_ENV ~PATH

仮想環境が再作成されます。最後にpip install -rで書き出したパッケージ情報から、パッケージを再インストールすれば、環境が復元できました。

$ pip install -r requirements.txt

おわりに

pythonに複数バージョンが必要になったらこの構成にpyenvを足すだけで良さそう。

direnv便利。