Sphinxを最新版にアップデートしてmake html出来なくなった時の対処法
make出来なくなった
Sphinxを最新版(v1.0.7)にアップグレードしたところ、make htmlコマンドが以下のようなエラーを吐くようになりました。
$ make html Running Sphinx v1.0.7 loading pickled environment... not yet created AccessInit: hash collision: 3 for both 1 and 1
make htmlが手癖になりそうなくらい惚れ込んでたのでこれは困りました。
とりあえずググってみた
とりあえず何も考えずにエラー内容そのままでググると、検索結果の先頭にこれまたまんまなタイトルの記事が見つかりました。
AccessInit: hash collision: 3 for both 1 and 1
ここを読むと、どうやらPIL(画像処理ライブラリ)のインポート方法に問題があることがわかります。
例えばこの記事にあるように、Djangoが
# Djangoはこの方法で呼び出している from PIL import Image
などと呼び出しているのに対し、pygmentsおよびdocutilsは
# pygmentsやdocutilsはこっち import Image import Image as PIL
などのように呼び出しています。
この2種類のPILのインポート方法はダブルスタンダード化していて、どっちで呼びだそうが呼ばれるものは同じPILなんです。が、Pythonインタプリタはこれら二つのImageモジュールが別物だと認識してしまうとのことです。なので名前衝突が起こってしまうというわけですね。
尚、最新のpygmentsはすでに「from PIL import 〜」方式に修正されています。docutilsは未だに「import Image」ですが。
Sphinxはというと
Sphinxの公式アナウンスでこんなのがありました。
Release 1.0.7 (Jan 15, 2011)
#599: Import PIL as from PIL import Image.
http://sphinx.pocoo.org/changes.html
「Import PILをfrom PIL import Imageに変更したよー」ってことですね。そうです。この修正によって「PILの二重呼び出し」現象が再現されてしまったわけです。
というわけでdocutilsを修正してみる
AccessInit: hash collision: 3 for both 1 and 1の最後で紹介されているdocutils patchに書かれている通りに、docutilsフォルダ(Python2x/Lib/site-packages/docutils)以下の3つのファイルを修正します。
まずはimages.py
場所はPython2x/Lib/site-packages/docutils/parsers/rst/directives/images.py
from docutils.parsers.rst.roles import set_classes try: import Image as PIL # PIL except ImportError: PIL = None
これを以下のように修正
from docutils.parsers.rst.roles import set_classes try: import PIL except ImportError: try: import Image as PIL # PIL except ImportError: PIL = None
続いてhtml4css1/__init__/py
場所はPython2x/Lib/site-packages/docutils/writers/html4css1/__init__.py
import time import re try: import Image # check for the Python Imaging Library except ImportError: Image = None
これまた以下のように
import time import re try: from PIL import Image # check for the Python Imaging Library except ImportError: try: import Image except ImportError: Image = None
最後にodf_odt/__init__.py
場所はPython2x/Lib/site-packages/docutils/writers/odf_odt/__init__.py
# # Is the PIL imaging library installed? try: import Image except ImportError, exp: Image = None
これも(ry
# # Is the PIL imaging library installed? try: from PIL import Image except ImportError: try: import Image except ImportError: Image = None
以上で修正は終わりです。
make html してみる
やったーちゃんと動いたー!
内容が内容なだけに他にも困ってる人がいるかもと思って記事に起こしてみたのでした。参考になれば幸いです。また、「それやっちゃまずいよ」とかあれば教えていただけると嬉しいです。
それと、終わったあとにこんな記事を見つけました↓
ノート
Python 環境 (easy_install) に Sphinx をインストールしてはいけません。 buildout で作成したバージョンと衝突する可能性があるので削除してください。他のプロジェクトで Sphinx が必要な場合は virtualenv を使用してください。
Plone 開発者マニュアルを Plone CMS にアップロードする方法 — Plone 開発者マニュアル v1.0 documentation
うんうん、Python環境は出来るだけ汚さないように積極的にvirtualenvを活用すべきってのは僕も賛成です。