/var/log/soymsk

id:soy_msk


pyenv + venv + direnv で作るPython3環境

pyenv + virtualenvの問題点

Pythonでの開発環境において、

  • 開発ホスト上に複数のバージョンのPythonをインストールしたい場合 … pyenv
  • プロジェクトごとに仮想環境を構築し、モジュールを切り替えたい場合 … virtualenv

の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にも載っています。

qiita.com

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環境にも応用できるかと思います。