Python

pyenv, virtualenvの仕組み

More than 1 year has passed since last update.

この記事の目的

pyenv, virtualenvがどのような仕組みでPython実行環境を作っているのか説明する。導入方法、使用方法には特に触れない。説明は参照サイトの翻訳で、それ以上の情報はない。

参照サイト

yyuu/pyenv
virtualenv

pyenv

概要

pythonのバージョンを同一端末内で使い分けるためのツール。作業ディレクトリ毎に用いるpythonのバージョンを設定できる。

仕組み

構成要素

pyenvでインストールされる各バージョンのpythonは下記のように保存される。ちなみにpyenvで指定するバージョン名はフォルダ名そのままである。

pyenv_structure
$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/に配置されるコマンド群である。一口に言うと、バージョン情報を探索したのち、該当するバージョンの同名コマンドを実行するコマンドである。具体的な手順は下記の通り。

  1. 環境変数PYENV_VERSIONを調べ、もしバージョン情報があれば、それを利用する。

  2. 環境変数PYENV_VERSIONに情報がない場合、.python-versionファイルが同ディレクトリにあれば、それに記載されたバージョンを利用する。

  3. 同ディレクトリに.python-versionファイルがなければ、親ディレクトリを探索し、.python-versionファイルが存在しないか調べる。

  4. 上記の探索でバージョン情報が見つからない場合、~/.pyenv/versionファイルに記載された情報を利用する。このファイルすらない場合、system標準にあるPythonを利用する。

このshimコマンドを利用するために、$HOME/.pyenv/shims/をシステム標準のコマンドがあるPATHより左側に$PATHを設定しなければならない。
directory:例
~/.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
# activateスクリプトから抜粋
PATH="$VIRTUAL_ENV/bin:$PATH"
unset PYTHONHOME

まとめ

pyenvのshimの仕組みはちょっと面白い。virtualenvがやってることはそんなに複雑ではない。pyenvにインストールしたバージョンを使いたい場合、次のようにすればよさそう。

$ virtualenv path-to-desired-env --python=$HOME/.pyenv/versions/2.7.8/