YAMAGUCHI::weblog

海水パンツとゴーグルで、巨万の富を築きました。カリブの怪物、フリーアルバイター瞳です。

Python3.3のvenvを試す

はじめに

こんにちは、Python界の情弱です。最近は「勉強会」という名を借りたリクルーティングが行われているようですが、賢良なる読者の皆様におかれましては、主催者の主旨、講師の方々のブログおよび公開レポジトリ等をご確認の上ご参加されていることでしょう。
それはさておき、Python3.3の公式リリースの足音が聞こえて参りました。このマイナーバージョンアップは実は非常に大きく、2年の長きにわたって実施されていたLanguage Moratorium*1を終え、ついにPythonが3系として完全に後方互換性を排除し始めるバージョンとなるわけです。*2
そんな中私が個人的に一押し注目中のvenvモジュールについて調べてみました。

venv a.k.a pyvenv

PEP 405でPython Virtual Environmentという提案がなされています。この提案の動機に関して、詳細は上記PEPを参照していただくとして、要はvirtualenv的な機能を標準でサポートしたほうがいいんじゃねえの?そしてvirtualenvみたいに全部まるっとコピーするのはだるいからもっと軽量な仮想環境が使えるようにしようぜ!ってことみたいです。

Python 3.3のインストール

とりあえず、Python 3.3が必要だということでMacPortsにあるPython 3.3 rc1をぶっこみます。

% port search python33
python33 @3.3.0rc1 (lang)
    An interpreted, object-oriented programming language
% sudo port install python33

早速venvが入っているか試してみましょう。

% python3.3 -c "import venv; print(venv.__doc__)"

Virtual environment (venv) package for Python. Based on PEP 405.

Copyright (C) 2011-2012 Vinay Sajip.
Licensed to the PSF under a contributor agreement.

usage: python -m venv [-h] [--system-site-packages] [--symlinks] [--clear]
            [--upgrade]
            ENV_DIR [ENV_DIR ...]

Creates virtual Python environments in one or more target directories.

positional arguments:
  ENV_DIR               A directory to create the environment in.

optional arguments:
  -h, --help            show this help message and exit
  --system-site-packages
                        Give the virtual environment access to the system
                        site-packages dir.
  --symlinks            Attempt to symlink rather than copy.
  --clear               Delete the environment directory if it already exists.
                        If not specified and the directory exists, an error is
                        raised.
  --upgrade             Upgrade the environment directory to use this version
                        of Python, assuming Python has been upgraded in-place.

動きましたね。ドキュメントに諸々書いてありますがとりあえず先に進みます。

pyvenvを試す

pyvenvというのはvenvモジュールの外部コマンドとしてのスクリプトで、中身はvenvモジュールのmain()を叩いているだけです。

  • pyvenv-3.3.py
#!/opt/local/Library/Frameworks/Python.framework/Versions/3.3/bin/python3.3
if __name__ == '__main__':
    import sys
    rc = 1
    try:
        import venv
        venv.main()
        rc = 0
    except Exception as e:
        print('Error: %s' % e, file=sys.stderr)
    sys.exit(rc)

では早速pyvenvを試してみます。まずはワークスペースの作成。

% pyvenv-3.3 venvtest
% tree venvtest 
venvtest
├── bin
│   ├── activate
│   ├── pydoc
│   ├── python -> python3.3
│   ├── python3 -> python3.3
│   └── python3.3 -> /opt/local/Library/Frameworks/Python.framework/Versions/3.3/bin/python3.3
├── include
├── lib
│   └── python3.3
│       └── site-packages
└── pyvenv.cfg

pyvenvにワークスペースまでのパスを指定すると必要なものをbootstrapで作成してくれます。さて、ここでおもむろにpyvenv.cfgといういかにも設定ファイルっぽいやーつを見てみます。

  • pyvenv.cfg
home = /opt/local/Library/Frameworks/Python.framework/Versions/3.3/bin
include-system-site-packages = false
version = 3.3.0

pyvenvはデフォルトではシステムのsite-packagesとは独立していますが、含めたい場合にはinclude-system-site-packagesをtrueにしてあげればいい。
いよいよこの仮想環境をアクティブにします。

% source bin/activate 
(venvtest) % deactivate
% 

ちゃんとPS1を置き換えてくれる親切心。このactivateというshell scriptを読み込むことで、$PATHの先頭に仮想環境のbinが追加されます。仮想環境から抜けるときはこのactivateというスクリプト内に定義されているdeactivateを叩くことで抜けられます。$PATHも直っています。
activateした状態で色々とパッケージを入れてみようと思います。残念ながら、pysetupはPython3.3.0のリリースではバンドルから外されたので、とりあえずdistributeを入れようと思います。

(venvtest) % curl -O "http://pypi.python.org/packages/source/d/distribute/distribute-0.6.28.tar.gz"
(venvtest) % tar xzf distribute-0.6.28.tar.gz
(venvtest) % cd distribute-0.6.28
(venvtest) % python setup.py install
(venvtest) % ls venvtest/bin
activate		easy_install-3.3	python			python3.3
easy_install		pydoc			python3
(venvtest) % ls venvtest/lib/python3.3/site-packages 
distribute-0.6.28-py3.3.egg		setuptools-0.6c11-py3.3.egg-info
easy-install.pth			setuptools.pth

binにeasy_installが追加されて、site-packagesも追加されてますね。pyvenvではない本体の方はどうなっているかというと

(venvtest) % ls /opt/local/Library/Frameworks/Python.framework/Versions/3.3/bin/easy_install*
zsh: no matches found: /opt/local/Library/Frameworks/Python.framework/Versions/3.3/bin/easy_install
(venvtest) % ls /opt/local/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages
README

先ほどインストールしたてなので、binにはeasy_installは入っておらず、site-packagesもREADME以外ありません。せっかくなのでvenvで作成した仮想環境にパッケージを入れてみましょう。

(venvtest) % easy_install-3.3 bucho
(venvtest) % python -c "import bucho; print(bucho.all_status())" 
田町で、京浜東北線から山手線に乗り換えにしくじる。この時間帯はあんまりsyncしてないのか。
...
一杯目はサイズだけ伝えると、湘南ゴールドを出してもらえるお店があって嬉しい。今日の店とか。

ちゃんとbuchoの最新ステータスが確認出来ましたね!一応site-packagesの方も確認してみます。

(venvtest) % cat venvtest/lib/python3.3/site-packages/easy-install.pth
import sys; sys.__plen = len(sys.path)
./distribute-0.6.28-py3.3.egg
./bucho-0.1.2-py3.3.egg
import sys; new=sys.path[sys.__plen:]; del sys.path[sys.__plen:]; p=getattr(sys,'__egginsert',0); sys.path[p:p]=new; sys.__egginsert = p+len(new)
(venvtest) % ls venvtest/lib/python3.3/site-packages/
bucho-0.1.2-py3.3.egg			setuptools-0.6c11-py3.3.egg-info
distribute-0.6.28-py3.3.egg		setuptools.pth
easy-install.pth

buchoモジュールがインストールされています。さて、この仮想環境をまっさらな状態に戻してみます。

(venvtest) % pyvenv-3.3 --clear venvtest
(venvtest) % ls venvtest/bin
activate	pydoc		python		python3		python3.3
(venvtest) % ls lib/python3.3/site-packages
(venvtest) %

全部消えてしまいました。また--upgradeオプションに関しては、コードを読む限り、環境で使っているPythonのバージョンを叩いたpyvenvが用いているPythonのバージョンに変更するというもののようです。素朴な疑問として、仮想環境へインストールしたパッケージと互換性がなくなる気がするのですが、そんなことをして大丈夫なんでしょうか。

所感

当初の思惑通り開発が進んでいれば、Python 3.3.0ではpysetup+pyvenvが入り、いままでpip+virtualenvでできていたようなことができるはずだったのですが、pysetupの取り込みに失敗したため片手落ちの状態になっている印象を受けます。とはいえ、標準で開発の仮想環境とパッケージ管理ができるというのは、非常に喜ばしいことなので今後に期待したいですね。

*1:PEP 3003、言語仕様の変更はしませんよ期間

*2:Python 3.1, 3.2に関しては重要な機能がそれぞれ2.6, 2.7にバックポートされていた