anyenvでpythonの異なるバージョンをディレクトリ別に切り替えてインストールする方法

githubのriywo/anyenv

最近pythonを使ってAI(人工知能)を扱う機会が出来たので、その開発環境の構築が必要になりました。 Macにはデフォルトでpython2系が入っていましたが、せっかくなので今回は新しいpython3系を使うことにしました。

後述する過去記事でMac上でanyenvを使ってnode.jsをインストールした環境がすでにあったので、今度はそれを使ってpythonをインストールすることにしました。Linuxでも同様にインストールできます。

anyenvのインストールとその確認方法

anyenvは簡単に言うと、python(node.jsなど他言語も含め)のバージョンを簡単に切り替えることができるバージョン管理ツールです。

anyenvのメリットと、そのインストール方法はこちらの記事中に書きました。

anyenvで特定のディレクトリに指定したバージョンのnode.jsをインストールしました。簡単にディレクトリ毎にバージョンを切り替える事が可能で、他の言語でも同じフローで応用できて環境構築手順がシンプルになるメリットがあります。

anyenv -v と打つとバージョン表示無しでanyenvと表示されれば、anyenvはインストールされていることの確認になります。

$ anyenv -v
anyenv
$

anyenvを使ってpythonをインストールする

pyenvをインストールする

pythonのバージョン管理ができるpyenvをインストールします(node.jsの場合はndenvになります)。

pyenvをインストールした後は、もう一度profileファイルを実行する必要があります。

$ anyenv install pyenv
$ source ~/.bash_profile
$ pyenv -v
pyenv 1.2.1-1-g6f27c91
$

pythonのインストール可能なバージョンを確認する

pyenv install -lでpythonのインストール可能なバージョンの一覧を確認できます。
今回は、python3系の現時点で最新の3.6.4をインストールすることにしました。

$ pyenv install -l | grep 3.6
  3.3.6
  3.6.0
  3.6-dev
  3.6.1
  3.6.2
  3.6.3
  3.6.4
$

以下のpythonのリリースノートで、最新のpythonのバージョンを確認することができます。

指定したバージョンのpythonをインストールする

そして、この一覧からバージョンを選択してマシンにインストールします。これは使用可能なpythonのバージョンを追加する作業です。

pyenv versionsは過去にインストールした使用可能なバージョンの一覧を表示します。

$ pyenv install 3.6.4
$ pyenv versions
...省略...
  3.3.6
  3.6.4
$

このpyenv install ${VERSION}を実行した時にエラーが発生した場合の対処法は、後述する補足説明を参照ください。

特定のディレクトリで使用するpythonのバージョンを選択する

マシンに複数インストールされた使用可能なバージョンの中から、使用するバージョンを1つ選択する形です。
pythonを実行したいディレクトリ(今回は/opt/app)に移動して、pyenv local ${VERSION}を実行します。

pythonコマンドに加えて、pipコマンドも一緒にインストールされていて、このディレクトリ配下ならどこでも実行可能です。

## pythonを実行したいディレクトリへ移動
$ cd /opt/app
$ ls -ld /opt/app
drwxr-xr-x  5 stedplay  wheel  160  1 20 09:42 /opt/app
$

## Macにデフォルトでインストールされているpythonのバージョンを確認
$ python --version
Python 2.7.10
$

## このディレクトリで実行したいpythonのバージョンを指定して使用可能にする
$ pyenv local 3.6.4
$ python --version
Python 3.6.4
$ pip --version
pip 9.0.1 from /Users/stedplay/.anyenv/envs/pyenv/versions/3.6.4/lib/python3.6/site-packages (python 3.6)
$

ちなみに、選択したpythonのバージョンは.python-versionというファイルがこのディレクトリに生成され、保存されます。

案件間で異なるバージョンを使用する場合は、案件のディレクトリ毎にこのファイルの内容も異なると言うことです。

$ cat /opt/app/.python-version 
3.6.4
$

.python-versionが保存されるためには、ログインユーザにこのディレクトリの書き込み権限が有る必要があります。権限が無い場合は、chownコマンドで付与します。

任意のディレクトリで使用するpythonのバージョンを選択する

基本的に上記までの作業で事が足りますが、特定のディレクトリ内でのみpython3系を使用する方法なので、例えばrootディレクトリに移動するとMac標準でインストールされているpython2系が実行されます。場所関係なく3系の同一バージョンで実行して良い場合はpyenv global ${VERSION}とすることで、任意のディレクトリで使用するデフォルトのバージョンを選択できます。

ここでは3.3.6を選択しました。

## pyenv local ${VERSION}を実行していないディレクトリへ移動
$ cd /

## Macにデフォルトでインストールされているpythonのバージョンを確認
$ python --version
Python 2.7.10
$

## 任意のディレクトリで実行したいpythonのバージョンを指定して使用可能にする
$ pyenv global 3.3.6
$ python --version
Python 3.3.6
$

pyenv globalで選択したpythonのバージョンは以下のパスに生成され、保存されます。

$ cat ~/.anyenv/envs/pyenv/version
3.3.6
$ 

ちなみに、pyenv localで選択したバージョンはpyenv globalより優先して採用されます。前述で作成したディレクトリに移動してpythonコマンドを実行すると、pyenv localで選択したバージョンで実行されます。

## pyenv local ${VERSION}を実行したディレクトリへ移動
$ cd /opt/app
$ python --version
Python 3.6.4
$

[補足] "pyenv install ${VERSION}"でエラーが発生した場合

指定したバージョンのpythonをインストールする時に、以下のようなエラーが発生する場合があります。

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

BUILD FAILED (OS X 10.13.2 using python-build 1.2.1-1-g6f27c91)

Inspect or clean up the working tree at /var/folders/sd/7n9qv0hs4pd40l4kswwdddww0000gn/T/python-build.20180120083858.79032
Results logged to /var/folders/sd/7n9qv0hs4pd40l4kswwdddww0000gn/T/python-build.20180120083858.79032.log

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

その場合はこちらのpyenvのissueにある以下のコマンドで、xcodeのコマンドラインツールをインストールすると、私の場合はエラーを解消できました。

$ xcode-select --install
xcode-select: note: install requested for command line developer tools
$
Xcodeがインストールされていない場合はこちら

すると以下のダイアログが表示されるので、[インストール]を押します。

Xcodeコマンドラインツールのインストールダイアログ

規約を確認して、[同意する]を押します。

Xcodeコマンドラインツールの使用規約

インストール完了まで待機して、このダイアログが表示されたら[完了]を押します。

Xcodeコマンドラインツールのインストール完了

そしてこちらの前述した手順に戻って再度進めると、エラーなくpythonの指定バージョンをインストールできるようになりました。

まとめ

anyenvを使って、「特定の」または「任意の」ディレクトリに指定したバージョンのpythonをインストールする方法をまとめました。

先日のnode.jsに引き続きanyenvでpythonもインストールしてみました。途中エラーが発生して回避策を講じたものの、大体がnode.js用の手順をpython用に置換(node -> pythonndenv -> pyenvなど)したコマンドで同じ流れでインストールすることができて、とても楽できました。

複数の言語をインストールする可能性がある場合は、anyenvを導入しておくのがオススメです。