PsychoPyをMacにインストールするには、2系統の方法があって、一つは、PsychoPyからバイナリをダウンロードしてきてインストールする方法。この方法の場合、Pythonも見えない形で一緒にインストールしてくれるのでPythonのバージョン問題やPythonとPsychoPyとの相性問題で悩む必要がなく簡単で早い。
もう一つは pip でインストールする方法である。エンジニア系の人だったらこっちの方がハードルが低いのではないか。公式サイトには両方のやり方が書いてある。
そもそもは両方をインストールしていて、pipでインストールしたPsychoPyも動いていたのだけど、あるとき、テキストエディターでコードを書いてターミナルで実行していたら、keyboadに関するコードがあると、コードがクラッシュするというのが発端。どうもintel MacではないM1やM2などのApple Siliconを積んだMacだとこのキーボードの問題が発生するらしい。以下のようなコードが1行あるだけでクラッシュした。
kb = keyboard.Keyboard()
ただ、バイナリインストールしたPsychoPyならば上記のコードがあっても動くので、バイナリ版とpip版でpythonとpsychopyのバージョンを合わせればクラッシュせずに済むのではないかと思った。なんとかバイナリ版とpip版で同じ挙動をpsychopyにさせたいと思ったのが、事の発端である。
pythonをインストールし直し、必要ならpsychopyもpipからインストールし直す。簡単に済む時はすむけれど、今回は七転八倒の悶絶を繰り返しなんとかインストール完了にたどりついた。何が有効で何がそうではなかったかは、今となってはよくわからない。自分的に肝心となるところだけ記述する。
- MacBook Air M2, 2022
- Ventura 13.6.7
最初、pipでインストールしたらこけて、なんでかなと思ったら、psychopyはpythonのバージョンが 3.8 か 3.10 しか正式にはサポートしていない。システムpythonは3.12で対象外だった。なので、pythonのバージョンを合わせてやる必要があるのではないか。
そう思って、当初はバイナリ版pythonの3.8や3.10をPythonのホームページからダウンロードしてきてインストールした。が、うまくいかなかった。しかも、複数のPythonをバイナリから入れて、どのように切り替えれば良いのかわからないという問題もある。フルパスで実行するか、エイリアスを書き換えるかだが、前者は面倒だし、後者はどこにエイリアスがあるのかよくわからない&書き換えたら元に戻すの忘れそうということで、この方法は頓挫。
次に、pyenvを使って複数pythonを共存させようとした。pyenvは、homebrewに頼らないかたちで実行してインストールした。そして、pyenvが入ったら、pyenvから、pythonのインストールがうまくいかないという事態が発生。せっかくpyenv入れたのにpythonのインストールに失敗するってなんやねん。
それで、pyenvの入れ方が悪かったのかと思い、brewでpyenvをインストールしなおしたが症状は変わらなかった。途中でXcodeやCommandLineToolsを入れ直したがだめだった。
どうもエラーを眺めていると、clangなどのコンパイルで問題が起こっているようで、M2 Macなどのintel Macから別のCPUに変わったことに起因するエラーのように感じられた。
なので、どうせさして使っていないしということでhomebrewを再インストールした。
そして、新生したhomebrewから pyenv をインストールした。
brew update
brew install pyenv
homebrewのアンインストール
そうしてpyenvが入って、pyenv経由でpythonをインストールしたがまたエラー。しかし今回は、どうも xz というインストールが不足しているらしいというのがエラーから読み取れた。
brew install xz
これで xz を入れて、再度 pythonのインストールを試みたところ、pythonはインストールできた。
この時、それ以前の試行錯誤から、M1/M2系 Mac には、特定のマイナーバージョンのPythonしかインストールできないという情報があった。他のバージョンを試していないので、わからないが、以下のバージョンのうち、自分が必要な3.8.13と3.10.3のインストールだけ試みて成功した。
3.7.13, 3.8.13, 3.9.11, 3.10.3
今回使いたい3.8系にしても3.10系にしても上記よりもより新しいマイナーバージョンが存在するが、そちらは指定せずに上記のバージョンを指定した。
pythonが入ったので、次はpipである。pipを実行するとエラーになった。どうもpipの指し示すpythonがすでに消えてしまっているpythonで、pythonが実行できずエラーになる。pipはインストールしなおしたが症状が改善しないので、そのpipファイルを削除して、それからもう一度pipをインストールした。
複数バージョンでpipを使う場合、複数のバージョンのpythonが共通のpipを使うことになるので、モジュールのバージョン管理がカオスになることが予想できたし、pipenvというそちらの管理ソフトもあるみたいだが、今回は割愛した。
そうしてやっと、psychopyのインストールである。
pip install psychopy
これでインストールを試みたが、当然のようにエラーになった。(長い)
Collecting tables<3.9 (from psychopy)
Using cached tables-3.8.0.tar.gz (8.0 MB)
Installing build dependencies ... done
Getting requirements to build wheel ... error
error: subprocess-exited-with-error
× Getting requirements to build wheel did not run successfully.
│ exit code: 1
╰─> [11 lines of output]
ld: library not found for -lhdf5
clang: error: linker command failed with exit code 1 (use -v to see invocation)
<string>:19: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
cpuinfo failed, assuming no CPU features: 'flags'
* Using Python 3.8.13 (default, Jun 15 2024, 16:01:24)
* Found cython 3.0.10
* USE_PKGCONFIG: True
.. ERROR:: Could not find a local HDF5 installation.
You may need to explicitly state where your local HDF5 headers and
library can be found by setting the ``HDF5_DIR`` environment
variable or by using the ``--hdf5`` command-line option.
というエラーでどうも、 hdf5というのが足りないらしい。
brew install hdf5
export HDF5_DIR="$(brew --prefix hdf5)"
これで再度psychopyのイントールを試みて、エラーだったがエラー内容は変わった。
Collecting tables<3.9 (from psychopy)
Using cached tables-3.8.0.tar.gz (8.0 MB)
Installing build dependencies ... done
Getting requirements to build wheel ... error
error: subprocess-exited-with-error
× Getting requirements to build wheel did not run successfully.
│ exit code: 1
╰─> [59 lines of output]
ld: library not found for -llzo2
clang: error: linker command failed with exit code 1 (use -v to see invocation)
ld: library not found for -llzo
clang: error: linker command failed with exit code 1 (use -v to see invocation)
ld: library not found for -lblosc
clang: error: linker command failed with exit code 1 (use -v to see invocation)
<string>:19: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
performance hint: tables/utilsextension.pxd:20:26: No exception value declared for 'get_native_type' in pxd file.
Users cimporting this function and calling it without the gil will always require an exception check.
Suggest adding an explicit exception value.
Error compiling Cython file:
------------------------------------------------------------
...
def _dump_h5_backtrace():
cdef object bt = []
if H5Ewalk(H5E_DEFAULT, H5E_WALK_DOWNWARD, e_walk_cb, <void*>bt) < 0:
^
------------------------------------------------------------
tables/utilsextension.pyx:384:47: Cannot assign type 'herr_t (unsigned int, const H5E_error_t *, void *) except? -1 nogil' to 'H5E_walk_t' (alias of 'herr_t (*)(unsigned int, H5E_error_t *, void *) noexcept nogil'). Exception values are incompatible. Suggest adding 'noexcept' to the type of 'e_walk_cb'.
cpuinfo failed, assuming no CPU features: 'flags'
* Using Python 3.8.13 (default, Jun 15 2024, 16:01:24)
* Found cython 3.0.10
* USE_PKGCONFIG: True
* pkg-config header dirs for HDF5: /opt/homebrew/Cellar/hdf5/1.14.3_1/include
* pkg-config library dirs for HDF5: /opt/homebrew/Cellar/hdf5/1.14.3_1/lib
* Found HDF5 headers at ``/opt/homebrew/Cellar/hdf5/1.14.3_1/include``, library at ``/opt/homebrew/Cellar/hdf5/1.14.3_1/lib``.
* Could not find LZO 2 headers and library; disabling support for it.
* Could not find LZO 1 headers and library; disabling support for it.
* Could not find bzip2 headers and library; disabling support for it.
* Could not find blosc headers and library; using internal sources.
* Found blosc2 headers at ``/private/var/folders/nn/c08xd2bx3nxcrpgyqrxtydhr0000gn/T/pip-build-env-j_r6v_9h/overlay/include``, library at ``/private/var/folders/nn/c08xd2bx3nxcrpgyqrxtydhr0000gn/T/pip-build-env-j_r6v_9h/overlay/lib``.
* Copying blosc2 runtime library to 'tables' dir because it was not found in standard locations
Compiling tables/utilsextension.pyx because it changed.
[1/1] Cythonizing tables/utilsextension.pyx
Traceback (most recent call last):
File "/Users/<username>/.pyenv/versions/3.8.13/lib/python3.8/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 353, in <module>
main()
File "/Users/<username>/.pyenv/versions/3.8.13/lib/python3.8/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 335, in main
json_out['return_val'] = hook(**hook_input['kwargs'])
File "/Users/<username>/.pyenv/versions/3.8.13/lib/python3.8/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 118, in get_requires_for_build_wheel
return hook(config_settings)
File "/private/var/folders/nn/c08xd2bx3nxcrpgyqrxtydhr0000gn/T/pip-build-env-j_r6v_9h/overlay/lib/python3.8/site-packages/setuptools/build_meta.py", line 325, in get_requires_for_build_wheel
return self._get_build_requires(config_settings, requirements=['wheel'])
File "/private/var/folders/nn/c08xd2bx3nxcrpgyqrxtydhr0000gn/T/pip-build-env-j_r6v_9h/overlay/lib/python3.8/site-packages/setuptools/build_meta.py", line 295, in _get_build_requires
self.run_setup()
File "/private/var/folders/nn/c08xd2bx3nxcrpgyqrxtydhr0000gn/T/pip-build-env-j_r6v_9h/overlay/lib/python3.8/site-packages/setuptools/build_meta.py", line 311, in run_setup
exec(code, locals())
File "<string>", line 928, in <module>
File "<string>", line 923, in get_cython_extfiles
File "/private/var/folders/nn/c08xd2bx3nxcrpgyqrxtydhr0000gn/T/pip-build-env-j_r6v_9h/overlay/lib/python3.8/site-packages/Cython/Build/Dependencies.py", line 1154, in cythonize
cythonize_one(*args)
File "/private/var/folders/nn/c08xd2bx3nxcrpgyqrxtydhr0000gn/T/pip-build-env-j_r6v_9h/overlay/lib/python3.8/site-packages/Cython/Build/Dependencies.py", line 1321, in cythonize_one
raise CompileError(None, pyx_file)
Cython.Compiler.Errors.CompileError: tables/utilsextension.pyx
[end of output]
note: This error originates from a subprocess, and is likely not a problem with pip.
error: subprocess-exited-with-error
× Getting requirements to build wheel did not run successfully.
│ exit code: 1
╰─> See above for output.
note: This error originates from a subprocess, and is likely not a problem with pip.
エラーを読むと相変わらずtablesというモジュールのインストールに失敗している。tablesは3.9.0より低いものが要求されていて、3.8.0が選択されて、インストールを試みて失敗している。
ここで、なぜか覚えてないが、直感的にもっと古いバージョンのtablesならばインストールが通るのではないかと思い、一つ下のバージョンのインストールを試した。
pip install tables==3.7.0
そうしたところ、tablesがインストールされた。
そして、どうせまたエラーが出るだろうと思いつつ psychopyのインストールにすすんだところ、今度はインストールが完了した。
pip install psychopy
というわけで、試行錯誤の末、psychopyをpip経由でインストールするのに成功した。これで、PsychoPy Coderで書いたスクリプをターミナルでも動かせる。