pyenv が homebrew でインストールした tcl-tk と動かない。

# 遭遇した問題

Macでpyenvを使ってインストールしたpythonから、tkinter を使おうとしたところ、次のエラーがでた。

    Traceback (most recent call last):
      File "./annotate.py", line 3, in <module>
        import tkinter
      File "/Users/???/.pyenv/versions/3.7.4/lib/python3.7/tkinter/__init__.py", line 36, in <module>
        import _tkinter # If this fails your Python may not be configured for Tk
    ModuleNotFoundError: No module named '_tkinter'

環境は、

* MacOS Catalina 10.15.1
* pyenv 1.2.15

# ググって見つかった（そして解決しなかった）方法

## pyenv で python を再インストールする

pyenv でpythonをインストールしている場合、一旦 uninstall して install し直すと解決するらしい。

ググって見つけたのは以下のページ:

* https://qiita.com/4hiziri/items/aba80f0bc92300ea22e2
* https://teratail.com/questions/190225

具体的には、↓な感じ。

    $ pyenv versions
     system
    * 3.7.5                 # 現在使われている python が 3.7.5 だったので
    $ pyenv uninstall 3.7.5 # python 3.7.5 をアンインストールして
    $ brew install tcl-tk   # homebrew で tcl-tk をインストールして
    $ export LDFLAGS="-L/usr/local/opt/tcl-tk/lib"      # tcl-tk の開発に必要な
    $ export CPPFLAGS="-I/usr/local/opt/tcl-tk/include" # 徹底を行ってから
    $ pyenv install 3.7.5   # 改めて python 3.7.5 をインストールする

しかし、再度 tkinter を実行してみると・・・

    $ python -m tkinter
    DEPRECATION WARNING: The system version of Tk is deprecated and may be removed 
    in a future release. Please don't rely on it. Set TK_SILENCE_DEPRECATION=1 to suppress this warning.
    Traceback (most recent call last):
      File "/Users/???/.pyenv/versions/3.7.4/lib/python3.7/runpy.py", line 193, in _run_module_as_main
        "__main__", mod_spec)
      File "/Users/???/.pyenv/versions/3.7.4/lib/python3.7/runpy.py", line 85, in _run_code
        exec(code, run_globals)
      File 
    "/Users/???/.pyenv/versions/3.7.4/lib/python3.7/tkinter/__main__.py", line 7, in <module>
    main()
      File "/Users/???/.pyenv/versions/3.7.4/lib/python3.7/tkinter/__init__.py", line 3988, in _test
        root = Tk()
      File "/Users/???/.pyenv/versions/3.7.4/lib/python3.7/tkinter/__init__.py", line 2025, in __init__
        self._loadtk()
      File "/Users/???/.pyenv/versions/3.7.4/lib/python3.7/tkinter/__init__.py", line 2040, in _loadtk
        % (_tkinter.TK_VERSION, tk_version))
    RuntimeError: tk.h version (8.6) doesn't match libtk.a version (8.5)

と別のエラーが出てしまう。
この場合、header は version 8.6 を使ってコンパイルされるが、実行時に参照されるライブラリが version 8.5 担っているということらしい。

さらにググるも、日本語の解は見つからず。

# 解決策

英語でググったところ、次のページが見つかった。

* https://github.com/pyenv/pyenv/issues/1375

これですね。

つまり、/usr/local/Cellar/pyenv/VERSION/plugins/python-build/bin/python-build を編集して、次のパッチを当てる（と言っても、銭湯が "!" となっている１行書き換える）。

    diff -c python-build.orig python-build
    *** python-build.orig	2019-12-10 17:47:04.000000000 +0900
    --- python-build.new	2019-12-11 11:53:17.000000000 +0900
    ***************
    *** 772,778 ****
            export CC=clang
          fi
          ${!PACKAGE_CONFIGURE:-./configure} --prefix="${!PACKAGE_PREFIX_PATH:-$PREFIX_PATH}" \
    !       $CONFIGURE_OPTS ${!PACKAGE_CONFIGURE_OPTS} "${!PACKAGE_CONFIGURE_OPTS_ARRAY}" || return 1
        ) >&4 2>&1
      
        { "$MAKE" $MAKE_OPTS ${!PACKAGE_MAKE_OPTS} "${!PACKAGE_MAKE_OPTS_ARRAY}"
    --- 772,778 ----
            export CC=clang
          fi
          ${!PACKAGE_CONFIGURE:-./configure} --prefix="${!PACKAGE_PREFIX_PATH:-$PREFIX_PATH}" \
    !       $CONFIGURE_OPTS --with-tcltk-includes='-I/usr/local/opt/tcl-tk/include' --with-tcltk-libs='-L/usr/local/opt/tcl-tk/lib -ltcl8.6 -ltk8.6            ' ${!PACKAGE_CONFIGURE_OPTS} "${!PACKAGE_CONFIGURE_OPTS_ARRAY}" || return 1
        ) >&4 2>&1
      
        { "$MAKE" $MAKE_OPTS ${!PACKAGE_MAKE_OPTS} "${!PACKAGE_MAKE_OPTS_ARRAY}"

それで、pyenv で python を再インストールすれば良い。

    $ pyenv uninstall 3.7.5
    $ pyenv install 3.7.5
    $ python -m tkinter

うまく行った。