注意 (2013.11.11)
この記事はもう古いので、いまはdistributeではなくてsetuptoolsをインストールしてください。setuptoolsはプロジェクトが再始動してdistributeよりも新しい実装になっています。
はじめに
こんにちは!Python界のポルナレフです。
,. -‐'''''""¨¨¨ヽ (.___,,,... -ァァフ| あ…ありのまま 今 起こった事を話すぜ! |i i| }! }} //| |l、{ j} /,,ィ//| 『おれがsetuptoolsを使ったらsetuptoolsのsetuptoolsは i|:!ヾ、_ノ/ u {:}//ヘ バグっていてdistributeのsetuptoolsはちゃんと動いた!』 |リ u' } ,ノ _,!V,ハ | /´fト、_{ル{,ィ'eラ , タ人 な… 何を言ってるのか わからねーと思うが /' ヾ|宀| {´,)⌒`/ |<ヽトiゝ おれも 何が起きたか わからなかった… ,゙ / )ヽ iLレ u' | | ヾlトハ〉 |/_/ ハ !ニ⊇ '/:} V:::::ヽ 頭がどうにかなりそうだった… // 二二二7'T'' /u' __ /:::::::/`ヽ /'´r -—一ァ‐゙T´ '"´ /::::/-‐ \ typoだとか設定ミスだとか / // 广¨´ /' /:::::/´ ̄`ヽ ⌒ヽ そんなチャチなもんじゃあ 断じてねえ ノ ' / ノ:::::`ー-、___/:::::// ヽ } _/`丶 /:::::::::::::::::::::::::: ̄`ー-{:::... イ もっと恐ろしいものの 片鱗を味わったぜ…
何が起きたのか見てください。
結論
先に結論だけ言っておきます。
[11/01/16 0:01:33] しみずかわ: なんか、pth_file.add()の実装にバグがあって、カレントディレクトリが追加対象dirの場合に追加してくれない、という現象っぽい
setuptools.egg内のsetuptoolsにはバグがある模様です。特にsetup.py developの時に起きるので開発中はdistribute.eggを使うほうが良さそうです。virtualenvを使っているときは--distributeを指定しましょう。virtualenvwrapperでも同様です。
$ python virtualenv.py --distribute ENV名 $ mkvirtualenv --distribute ENV名
夜中にお付き合いいただいた清水川先生有難うございます!ここで宣伝させていただきます!
再現環境
- ホスト環境
OS | Mac OS X 10.6.6 |
---|---|
Python | 2.6.6 |
virtualenv | 1.5.1 |
virtualenvwrapper | 2.5.3 |
- virtualenv環境1
Python | 2.6.6 |
---|---|
setuptools | setuptools-0.6c11-py2.6 |
- virtualenv環境2
Python | 2.6.6 |
---|---|
setuptools | distribute-0.6.14-py2.6 |
状況
次のディレクトリ構成でpython setup.py developを使ってjinja2をインストールする。docs内でimport jinja2出来るようにしたい。
$ tree -L 1 . ├── CHANGES ├── Jinja2.egg-info ├── docs ├── jinja2 └── setup.py
で、何が起きたかと言うと、普通なら問題なくimportできるはずが、できない、という状況。
再現
setuptoolsを使った場合
まずは普通にvirtualenvをしたところで実行してみる。
$ mkvirtualenv virtualenv1 (virtualenv1)$ python setup.py -vvv develop ... reading manifest file 'Jinja2.egg-info/SOURCES.txt' writing manifest file 'Jinja2.egg-info/SOURCES.txt' running build_ext Creating /Users/ymotongpoo/.virtualenvs/virtualenv1/lib/python2.6/site-packages/Jinja2.egg-link (link to .) Adding Jinja2 2.6 to easy-install.pth file Installed /Users/ymotongpoo/docs/jinja2_docjp Processing dependencies for Jinja2==2.6 Finished processing dependencies for Jinja2==2.6
あれ、verboseにしてるのにpthファイルの絶対パスが表示されない。ほんとにpthファイルに書きこまれたのかな...?みてみよう。
(virtualenv1)$ pwd /Users/ymotongpoo/.virtualenvs/virtualenv1/lib/python2.6/site-packages (virtualenv1)$ cat easy-install.pth import sys; sys.__plen = len(sys.path) ./setuptools-0.6c11-py2.6.egg ./pip-0.8.1-py2.6.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)
あれ、書かれてない...どうしてだろう?ソースコードを見てみます。
- setuptools-0.6c11-py2.6.egg/command/easy_install.py
def update_pth(self,dist): ... else: log.info("Adding %s to easy-install.pth file", dist) self.pth_file.add(dist) # add new entry if dist.location not in self.shadow_path: self.shadow_path.append(dist.location) if not self.dry_run: self.pth_file.save() if dist.key=='setuptools': # Ensure that setuptools itself never becomes unavailable! # XXX should this check for latest version? ...
なのでself.pth_file.save()を見てみます。
def save(self): """Write changed .pth file back to disk""" if not self.dirty: return data = '\n'.join(map(self.make_relative,self.paths)) if data: log.debug("Saving %s", self.filename) ... f.write(data); f.close() elif os.path.exists(self.filename): log.debug("Deleting empty %s", self.filename) os.unlink(self.filename) # ここの節追加。 else: log.info("bucho!, %s", self.filename) self.dirty = False
ここで"Saving〜"っていう出力が先程のログにないから、上のソースにあるみたいにelse節を追加して再度setup.py develop実行したけど、やっぱりログが表示されない。pthも更新されていない。当然この状態でdocsディレクトリに行ってもimportは出来ない。
(virtualenv1)$ pwd /Users/ymotongpoo/docs/jinja2_docjp/docs (virtualenv1)$ python -c "import jinja2; print jinja2.__version__" Traceback (most recent call last): File "<string>", line 1, in <module> ImportError: No module named jinja2
distributeを使った場合
今度はdistributeを使ったvirtualenv環境を作って実行してみる。
$ mkvirtualenv --distribute virtualenv2
これで再度setup.py developしてみる。
(virtualenv2)$ python setup.py -vvv develop ... writing manifest file 'Jinja2.egg-info/SOURCES.txt' running build_ext Creating /Users/ymotongpoo/.virtualenvs/virtualenv2/lib/python2.6/site-packages/Jinja2.egg-link (link to .) Adding Jinja2 2.6 to easy-install.pth file Saving /Users/ymotongpoo/.virtualenvs/virtualenv2/lib/python2.6/site-packages/easy-install.pth Installed /Users/ymotongpoo/docs/jinja2_docjp Processing dependencies for Jinja2==2.6 Finished processing dependencies for Jinja2==2.6
今度はちゃんと"Saving〜"が表示されている!でeasy-install.pthも確認する。
(virtualenv2)$ cat /Users/ymotongpoo/.virtualenvs/jinja2doc2/lib/python2.6/site-packages/easy-install.pth import sys; sys.__plen = len(sys.path) ./distribute-0.6.14-py2.6.egg ./pip-0.8.1-py2.6.egg /Users/ymotongpoo/docs/jinja2_docjp 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)
ちゃんとjinja2_docjpが書きこまれている!そしてdocsディレクトリでjinja2をインポートしてみる。
(virtualenv2)$ pwd /Users/ymotongpoo/docs/jinja2_docjp/docs (virtualenv2)$ python -c "import jinja2; print jinja2.__version__" 2.6
出来ました!