またPyenv環境に戻してみた

動機

ライブラリ開発とかしてるとどうしてもhomebrewだけではつらくなる(python3.6が入ってる状態でbrew upgradeしてpython3.7に上がると、brew cleanup叩いた時点でpython3.6が消される)

公式からバージョンごとにインストーラー落としてきて入れるというのも考えたが、pipenvにはpyenvと連携するオプションが用意されてるし、CircleCIも内部でpyenv使ってるしpoetryの作者もとあるissueに対する返信で「pyenvを使うことを強く推奨する」なんて言ってたのでもう海外でもpyenvが市民権得たのかなーとか思った次第。じゃあもうpyenvでいいやーと。

事前確認

brewで入れているPython

  • 2.7.10
  • 3.7.0

pyenvのインストール

~ $ brew install pyenv
==> Installing dependencies for pyenv: autoconf
==> Installing pyenv dependency: autoconf
==> Downloading https://homebrew.bintray.com/bottles/autoconf-2.69.mojave.bottle.4.tar.gz
######################################################################## 100.0%
==> Pouring autoconf-2.69.mojave.bottle.4.tar.gz
==> Caveats
Emacs Lisp files have been installed to:
  /usr/local/share/emacs/site-lisp/autoconf
==> Summary
🍺  /usr/local/Cellar/autoconf/2.69: 71 files, 3.0MB
==> Installing pyenv
==> Downloading https://homebrew.bintray.com/bottles/pyenv-1.2.8.mojave.bottle.tar.gz
######################################################################## 100.0%
==> Pouring pyenv-1.2.8.mojave.bottle.tar.gz
🍺  /usr/local/Cellar/pyenv/1.2.8: 612 files, 2.4MB
==> Caveats
==> autoconf
Emacs Lisp files have been installed to:
  /usr/local/share/emacs/site-lisp/autoconf

pyenvを使えるようにするために、bash等の場合は.bash_profile等にパスの追記等が必要だが、自分はfish shell & fisherman を使っているので、このへんはプラグインを入れるだけでOK.

~ $ fisher pyenv
Installing 1 plugin/s
OK Fetch pyenv github.com/fisherman/pyenv
Done in 2s 26ms

python3.6をインストールしてみるも失敗する

~ $ pyenv install 3.6.7
python-build: use openssl from homebrew
python-build: use readline from homebrew
Downloading Python-3.6.7.tar.xz...
-> https://www.python.org/ftp/python/3.6.7/Python-3.6.7.tar.xz
Installing Python-3.6.7...
python-build: use readline from homebrew

BUILD FAILED (OS X 10.14 using python-build 20180424)

Inspect or clean up the working tree at /var/folders/kb/knxvk74s36s20fd1n2sh7g200000gq/T/python-build.20181107053928.7189
Results logged to /var/folders/kb/knxvk74s36s20fd1n2sh7g200000gq/T/python-build.20181107053928.7189.log

Last 10 log lines:
  File "/private/var/folders/kb/knxvk74s36s20fd1n2sh7g200000gq/T/python-build.20181107053928.7189/Python-3.6.7/Lib/ensurepip/__main__.py", line 5, in <module>
    sys.exit(ensurepip._main())
  File "/private/var/folders/kb/knxvk74s36s20fd1n2sh7g200000gq/T/python-build.20181107053928.7189/Python-3.6.7/Lib/ensurepip/__init__.py", line 204, in _main
    default_pip=args.default_pip,
  File "/private/var/folders/kb/knxvk74s36s20fd1n2sh7g200000gq/T/python-build.20181107053928.7189/Python-3.6.7/Lib/ensurepip/__init__.py", line 117, in _bootstrap
    return _run_pip(args + [p[0] for p in _PROJECTS], additional_paths)
  File "/private/var/folders/kb/knxvk74s36s20fd1n2sh7g200000gq/T/python-build.20181107053928.7189/Python-3.6.7/Lib/ensurepip/__init__.py", line 27, in _run_pip
    import pip._internal
zipimport.ZipImportError: can't decompress data; zlib not available
make: *** [install] Error 1

最近Mojaveにアップグレードしたのが原因だった

mac os Mojave にアップグレードしたら bundle install が失敗する事象を解決した - Qiita

~ $ open /Library/Developer/CommandLineTools/Packages/
The file /Library/Developer/CommandLineTools/Packages does not exist.

上記リンクのQiita記事を参考にopenしてみるも、無いって言われる。記事の一番下の参照元リンク先みるとxcode-selectが必要っぽい。

~ $ xcode-select --install
xcode-select: note: install requested for command line developer tools

インストール完了後、再びopenコマンド実行すると今度はちゃんとフォルダが開くので、macOS_SDK_headers_for_macOS_10.14.pkgをダブルクリックでインストールする。

再びpyenvでpython3.6をインストールすると、今度は無事成功。

それぞれのPythonを呼び出せるようにする

simlink作成(非推奨)

tox等で使えるよう、python3.6コマンドで呼び出せるようにしたい。何も考えずに最初はsimlinkで対応した。

$ cd /usr/local/bin
$ ln -s ~/.pyenv/versions/3.6.7/bin/python3.6 .

でも後で気づいたが公式のやりかたがあった

pyenv global コマンド

~ $ pyenv versions
* system (set by /Users/kk6/.pyenv/version)
  2.7.15
  3.4.9
  3.5.6
  3.6.7

上記のような状態で、とりあえず3系全部動くようにしたいとする。pyenv globalに使いたいバージョンを列挙すればいいだけ。

~ $ pyenv global 3.4.9 3.5.6 3.6.7
~ $ pyenv versions
  system
  2.7.15
* 3.4.9 (set by /Users/kk6/.pyenv/version)
* 3.5.6 (set by /Users/kk6/.pyenv/version)
* 3.6.7 (set by /Users/kk6/.pyenv/version)
~ $ python3.5
Python 3.5.6 (default, Nov  7 2018, 06:07:53)
[GCC 4.2.1 Compatible Apple LLVM 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 

これだけ。いちいちsimlink張るより楽。ただ、simlinkのほうが起動は速い。

【追記】

pyenv global するとき、バージョンが新しいものから列挙してやらないとpython3コマンドが3.4を見に行ったりするので以下のようにする。

$ pyenv global 3.7.1 3.6.7 3.5.6 3.4.9 2.7.15

brewで入れたpython3.7をどうするか問題

brewpythonとpyenvのpython混在とか地獄を見そうなのでbrewpythonを消そうと思ったが…

~ $ brew uninstall python3
Error: Refusing to uninstall /usr/local/Cellar/python/3.7.0
because it is required by thefuck and vim, which are currently installed.
You can override this and force removal with:
  brew uninstall --ignore-dependencies python3

python3に依存してるやつらがいるから消せないとのこと。

thefuckに関してはわりとどうでもいい。vimもいい機会だしneovimにするのもありかもしれない。pyenvのpython3.7インストールしたら問題無さそうな気もするし、問題があればpythonインストール後にこいつらをbrewでインストールし直すのでもいけそうではある。

brewpython消してpyenvで入れ直した

やっぱり3.7だけbrewで他のバージョンがpyenvなの気持ち悪すぎるのでpyenvに統一する。

$ brew uninstall thefuck vim python3したあと$ pyenv install 3.7.1した。

で、既存のvenvが壊れるのは想定内で、pipenvが壊れるのも想定内(brewのpython3.7で入れていた)。ただ、pipも動かないとは思ってなかった。

$ pipenv
Failed to execute process '/Users/kk6/.local/bin/pipenv'. Reason:
The file '/Users/kk6/.local/bin/pipenv' specified the interpreter '/usr/local/opt/python/bin/python3.7', which is not an executable command.
$ pip
Failed to execute process '/usr/local/bin/pip'. Reason:
The file '/usr/local/bin/pip' specified the interpreter '/usr/local/opt/python/bin/python3.7', which is not an executable command.
$ which pip
/usr/local/bin/pip

エラーメッセージ見れば分かる通り、/usr/local/bin/にゴミが残っている。ついでにpip3も消しておく。

$ which pip
/Users/kk6/.pyenv/shims/pip
$ pip

Usage:
  pip <command> [options]

Commands:
  install                     Install packages.
  download                    Download packages.
  ...

これで動くようになった。

あとはpipenvを入れ直す。

$ pip install --user pipenv

以上でひとまずpyenvへの移行完了です。