pyenv + venv + direnv で作るPython3環境
pyenv + virtualenvの問題点
Pythonでの開発環境において、
の2つの組み合わせは一般的に使われているものかと思います。
virtualenvにおける、仮想環境切り替えの煩わしさ
virtualenvで開発環境を構築した場合、仮想環境 を切り替えるためには、プロジェクトのディレクトリ配下で、毎回 source ./{virtualenv directory}/bin/activate
しなければなりません。
この、仮想環境の切り替えを手動で行うのは開発中なかなか面倒なのと、いろいろなプロジェクトを触っているとついつい忘れがちになります。
pyenv + pyenv-virtualenvにするか?
pyenv と pyenv-virtualenv(プラグイン) を使えば、プロジェクトディレクトリにcdしたときに仮想環境を自動で切り替えてくれるので、手動による煩わしさはなくなります。
しかしながら、pyenvが管理するバージョンの中に、Python自体のバージョンと、virtualenvによる仮想環境が混在する状態になってしまいます。 プロジェクトが少ない段階ではこれでも十分なのですが、プロジェクトが増えてきた場合に、非常に管理しづらくなってきます。
このように、基本的な仮想環境の管理はvirtualenv方式がよいのですが、その仮想環境の切り替えは自動でやりたい、という場合には、direnvを使うとよさそうです。
そこで今回、 pyenv + venv(virtualenv) + direnv を使って、Python3開発環境を構築してみました。
pyenv のインストール
今回、venvを使うのでPython3 を入れておきます。
pyenv install 3.6.1 # versionは3.xのものを適宜 # 適当なテスト用プロジェクトディレクトリを作成 mkdir ~/myproject cd ~/myproject pyenv local 3.6.1 pyvenv my_venv
direnv
direnvはディレクトリごとに環境変数を切り替えることができるツールで、特定のディレクトリにいるときだけ環境変数をsetし、ディレクトリから抜けるときにunsetということをすべて自動的に行ってくれます。
Qiitaにも載っています。
direnv のインストール
インストールは非常に簡単です。
git clone http://github.com/zimbatm/direnv cd direnv sudo make install
また、以下の内容を.zshrc
に追加します。
eval "$(direnv hook zsh)" show_virtual_env() { if [ -n "$VIRTUAL_ENV" ]; then echo "($(basename $VIRTUAL_ENV))" fi } PS1='$(show_virtual_env)'$PS1
2行目以下は、direnvを使った場合にそのままでは仮想環境名がプロンプトに表示されないのですが、 その対策のために必要になります。
direnvの使い方
環境変数を切り替えたいディレクトリ、ここでは開発プロジェクトのディレクトリ配下に.envrc
というファイルを作成します。
direnvは、cd先のディレクトリ配下にこの.envrc
スクリプトが存在する場合にそのスクリプトをbashで実行し、スクリプト内でexportされた環境変数を、現在のシェルにsetします。
$ cat ./.envrc HOGE="fuga" export HOGE # この変数がディレクトリ以下でのみ有効になる
また、このディレクトリから更に別のディレクトリに移動した場合には、setされた環境変数は自動でunsetされます。
この機能を利用して、venvの開発環境の自動切り替えを実現させます。
.envrc
.envrcには以下のようにして保存します
source ./my_venv/bin/activate
これだけで準備完了です。
仮想環境の自動切り替え
以上の準備ができたらシェルを再起動して試してみます。
$ cd ~/myproject direnv: loading .envrc direnv: export +VIRTUAL_ENV ~PATH (my_venv) $ $ which pip ~/myproject/my_venv/bin/pip
自動で仮想環境が有効になりました。
※direnv: error .envrc is blocked. Run 'direnv allow' to approve its content.
というエラーが出た場合は direnv allow .
を実行します。
また、ディレクトリから抜けると、仮想環境が自動的に無効になることもわかります。
$ cd ~/ direnv: unloading $ which pip ~/.pyenv/shims/pip
仮想環境の自動切り替えが実現できました! これでプロジェクトが増えても安心できそうです。
また、今回pyvenvを使いましたが、virtualenvでも同様にできるはずですので、Python2環境にも応用できるかと思います。