この記事の目的
pyenv, virtualenvがどのような仕組みでPython実行環境を作っているのか説明する。導入方法、使用方法には特に触れない。説明は参照サイトの翻訳で、それ以上の情報はない。
参照サイト
pyenv
概要
pythonのバージョンを同一端末内で使い分けるためのツール。作業ディレクトリ毎に用いるpythonのバージョンを設定できる。
仕組み
構成要素
pyenvでインストールされる各バージョンのpythonは下記のように保存される。ちなみにpyenvで指定するバージョン名はフォルダ名そのままである。
$HOME/.pyenv/shims/ # pyenvの仕組みの核。各shimコマンドが配置される。
|-/versions/2.7.8/ # インストールしたPythonインタプリタ
|-/3.4.2/ # 例として2.7.8, 3.4.2, pypy-2.4.0をインストールした場合このようになる
|-/pypy-2.4.0/
|-/version # globalで使うpythonのバージョン情報ファイル
また、python local
コマンドを使うことで、任意の作業ディレクトリに.python-version
ファイルが配置される。
python global
コマンドでは、$HOME/.pyenv/version
ファイルが編集される。
.python-version
と$HOME/.pyenv/version
ファイルには、名前の通り利用するpythonのversion情報が記述されているのみである。
そして$HOME/.pyenv/shims/
以下にshimコマンドが作成される。これについては次節で説明する。
shimとバージョン切り替えの仕組み
shimコマンドとは、pythonコマンド(python, pip等)と同名で、$HOME/.pyenv/shims/
に配置されるコマンド群である。一口に言うと、バージョン情報を探索したのち、該当するバージョンの同名コマンドを実行するコマンドである。具体的な手順は下記の通り。
-
環境変数
PYENV_VERSION
を調べ、もしバージョン情報があれば、それを利用する。 -
環境変数
PYENV_VERSION
に情報がない場合、.python-version
ファイルが同ディレクトリにあれば、それに記載されたバージョンを利用する。 -
同ディレクトリに
.python-version
ファイルがなければ、親ディレクトリを探索し、.python-version
ファイルが存在しないか調べる。 -
上記の探索でバージョン情報が見つからない場合、
~/.pyenv/version
ファイルに記載された情報を利用する。このファイルすらない場合、system標準にあるPythonを利用する。
このshimコマンドを利用するために、$HOME/.pyenv/shims/
をシステム標準のコマンドがあるPATHより左側に$PATHを設定しなければならない。
~/.pyenv/shims:/usr/local/bin:/usr/bin:/bin
ちなみに、pyenv rehash
はこのshimsコマンドを現在インストールされてるpythonバージョン群に基づいて再構成するコマンドである。
virtualenv
virtualenvで構築されるディレクトリ
virtualenvコマンドで任意のディレクトリにPython実行環境を作成できる。このディレクトリ構成は単にPythonインタプリタのディレクトリと同じ構成である。Pythonコマンドは、自身の親ディレクトリにあるinclude, libディレクトリを参照するようだ。なので、virtualenvはただそのディレクトリ構成を作成し、必要なモノを入れ込むだけである。ちなみにPythonコマンドなどは、シンボリックリンクをはるのみである。実物をコピーしたい場合は--always-copy
オプションを使う。
# $VIRTUAL_ENVはvirtualenvコマンドで作成したディレクトリ
$VIRTUAL_ENV/bin/ # Python, pip等実行ファイル群
|-/include/ # C headerが配置される
|-/lib/ # 追加ライブラリが配置される
|-/pythonX.X/site-package
activate scriptで設定される環境変数
$PATH
に$VIRTUAL_ENV/bin
を追加するだけ。python実行を、$VIRTUAL_ENV/bin/python
としても、仮想環境のPythonを問題なく実行できそう。
# activateスクリプトから抜粋
PATH="$VIRTUAL_ENV/bin:$PATH"
unset PYTHONHOME
まとめ
pyenvのshimの仕組みはちょっと面白い。virtualenvがやってることはそんなに複雑ではない。pyenvにインストールしたバージョンを使いたい場合、次のようにすればよさそう。
$ virtualenv path-to-desired-env --python=$HOME/.pyenv/versions/2.7.8/