Homebrewでpyqt5をインストールした際に発生したエラー
Homebrew経由でpyqt5
をインストールしたところ、python3 configure.py
実行中に以下のエラーが出た。
...
File "configure.py", line 2693, in main
target_config.from_introspection(opts.verbose, opts.debug)
File "configure.py", line 733, in from_introspection
self.py_pylib_dir = pylib_dir
UnboundLocalError: local variable 'pylib_dir' referenced before assignment
...
configure.pyの該当箇所は以下の通り。py_pylib_dir
への変数が代入されないのは、dynamic_pylib
が偽の時だと分かる。
dynamic_pylib
は、--enable-framework
というキーがあるかを判別しているようだ。
...
# Use distutils to get the additional configuration.
from distutils.sysconfig import get_config_vars
ducfg = get_config_vars()
config_args = ducfg.get('CONFIG_ARGS', '')
if sys.platform == 'darwin':
dynamic_pylib = '--enable-framework' in config_args
else:
dynamic_pylib = '--enable-shared' in config_args
if dynamic_pylib:
pyshlib = ducfg.get('LDLIBRARY', '')
exec_prefix = ducfg['exec_prefix']
multiarch = ducfg.get('MULTIARCH', '')
libdir = ducfg['LIBDIR']
if glob.glob('%s/lib/libpython%d.%d*' % (exec_prefix, py_major, py_minor)):
pylib_dir = exec_prefix + '/lib'
elif multiarch != '' and glob.glob('%s/lib/%s/libpython%d.%d*' % (exec_prefix, multiarch, py_major, py_minor)):
pylib_dir = exec_prefix + '/lib/' + multiarch
elif glob.glob('%s/libpython%d.%d*' % (libdir, py_major, py_minor)):
pylib_dir = libdir
else:
pylib_dir = ''
else:
pyshlib = ''
self.py_pylib_dir = pylib_dir
self.py_pylib_lib = pylib_lib
self.py_pyshlib = pyshlib
...
sysconfig
モジュールによる構成情報の確認
ではget_config_vars
関数で取得できる辞書と、そのキーのCONFIG_ARGS
はどのような情報を表しているのか。
公式のリファレンスを見ると、「引数がない場合、現在のプラットフォームに関するすべての構成変数の辞書を返します。」という記述がある。「構成変数」というのは同ページで説明されているように、Pythonのビルド時(configure
/make
)に決定される情報が全て入っている。例えばCONFIG_ARGS
には./configure
実行時に指定した引数が格納されている。
get_config_vars
で取得できる内容は、sysconfig
モジュールを直接実行すると簡単に取得できる。実際に取得した結果、確かに--enable-framework
は入っていない。
(ref.)
http://www.warp1337.com/content/python-32-get-compile-options-get-configargs
https://github.com/python/cpython/blob/master/Lib/sysconfig.py#L694
$ python -m sysconfig | grep CONFIG_ARGS
CONFIG_ARGS = "'--prefix=/Users/FGtatsuro/.anyenv/envs/pyenv/versions/3.4.2' '--libdir=/Users/FGtatsuro/.anyenv/envs/pyenv/versions/3.4.2/lib' 'LDFLAGS=-L/usr/local/opt/readline/lib -L/usr/local/opt/readline/lib -L/Users/FGtatsuro/.anyenv/envs/pyenv/versions/3.4.2/lib ' 'CPPFLAGS=-I/usr/local/opt/readline/include -I/usr/local/opt/readline/include -I/Users/FGtatsuro/.anyenv/envs/pyenv/versions/3.4.2/include '"
そもそも--enable-framework
はなんなのか、というのはPythonのREADMEに記載がある。指定することにより、フレームワーク形式でPythonをビルドできる(フレームワーク形式についてはこちら参照)。この引数がデフォルトでは指定されないため、自身の環境で使用しているPython(pyenv経由でインストール)はフレームワーク形式でビルドされていなかった。
(PythonのREADMより抜粋)
* ``--enable-framework[=DIR]``
If this argument is specified the build will create a Python.framework rather
than a traditional Unix install. See the section
_`Building and using a framework-based Python on Mac OS X` for more
information on frameworks.
対処方法
HomebrewでインストールしたPythonを使う
Homebrewはデフォルトで--enable-framework
を指定してビルドしている。
(ref.) https://github.com/Homebrew/homebrew/blob/master/Library/Formula/python3.rb#L77
$ /usr/local/bin/python3 -m sysconfig | grep CONFIG_ARGS
CONFIG_ARGS = "'--prefix=/usr/local/Cellar/python3/3.4.2_1' '--enable-ipv6' '--datarootdir=/usr/local/Cellar/python3/3.4.2_1/share' '--datadir=/usr/local/Cellar/python3/3.4.2_1/share' '--enable-framework=/usr/local/Cellar/python3/3.4.2_1/Frameworks' '--without-gcc' 'CFLAGS=-I/usr/local/include -I/usr/local/opt/sqlite/include' 'LDFLAGS=-L/usr/local/lib -L/usr/local/opt/sqlite/lib' 'MACOSX_DEPLOYMENT_TARGET=10.9' 'CC=clang'"
ビルド時に--enable-framework
を指定する(pyenv)
pyenvは環境変数PYTHON_CONFIGURE_OPTS
を指定することで、ビルド時の設定を変更できる。
(ref.) https://github.com/yyuu/pyenv/issues/99
$ env PYTHON_CONFIGURE_OPTS="--enable-framework" pyenv install 3.3.6
$ pyenv global 3.3.6
$ ~/.anyenv/envs/pyenv/shims/python -m sysconfig | grep CONFIG_ARGS
CONFIG_ARGS = "'--prefix=/Users/tatsuro/.anyenv/envs/pyenv/versions/3.3.6' '--libdir=/Users/tatsuro/.anyenv/envs/pyenv/versions/3.3.6/lib' '--enable-framework' '--enable-framework=/Users/tatsuro/.anyenv/envs/pyenv/versions/3.3.6' 'LDFLAGS=-L/usr/local/opt/readline/lib -L/usr/local/opt/readline/lib -L/Users/tatsuro/.anyenv/envs/pyenv/versions/3.3.6/lib ' 'CPPFLAGS=-I/usr/local/opt/readline/include -I/usr/local/opt/readline/include -I/Users/tatsuro/.anyenv/envs/pyenv/versions/3.3.6/include '"
最後になるが、Virtualenv環境作成時に指定したPythonがフレームワーク形式でビルドされていない場合、作成した環境で使用するPythonも同様にフレームワーク形式でビルドされていないものであるため注意すること。