pyenvによる仮想Python環境をAWS Cloud9上で構築する
こんにちは、CX事業本部の若槻です。
AWS Cloud9上でpyenvによる仮想Python環境を構築して作業するディレクトリごとに異なるPythonバージョンを利用する場合の手順を確認したのでご紹介します。
確認してみた
環境の初期設定
pyenvを公式リポジトリからgitクローンします。
$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv
クローンしたpyenvが実行できることを確認します。
$ ~/.pyenv/bin/pyenv --version
pyenv 1.2.17-1-g89786b90
pyenvコマンドへパスを通しておきます。
$ export PATH="$HOME/.pyenv/bin:$PATH"
パス指定なしでpyenvを実行できるようになりました。
$ pyenv --version
pyenv 1.2.15-1-g49bf5952
pyenv init
によりpyenv global
やpyenv local
実行時にpythonの実行パスの差し替えをできるようにします。
$ eval "$(pyenv init -)"
※深くは調べられていませんが、pyenv init
の実行により内部では以下の処理が行われているようです。
$ echo "$(pyenv init -)"
export PATH="/home/ec2-user/.pyenv/shims:${PATH}"
export PYENV_SHELL=bash
source '/home/ec2-user/.pyenv/libexec/../completions/pyenv.bash'
command pyenv rehash 2>/dev/null
pyenv() {
local command
command="${1:-}"
if [ "$#" -gt 0 ]; then
shift
fi
case "$command" in
rehash|shell)
eval "$(pyenv "sh-$command" "$@")";;
*)
command pyenv "$command" "$@";;
esac
}
pyenvでPythonバージョンを切り替える
pyenvの初期設定ができたので、実際にPythonバージョンを切り替えてみます。
現在の既定のPythonバージョンは3.6.10です。
$ python --version
3.6.10
pyenvでインストールできるPythonバージョンを確認してみます。結果は省略していますが、2.X.Xや3.X.Xのほかにもいろいろ利用できるようです。
$ pyenv install -l
Available versions:
2.1.3
2.2.3
…
(省略)
…
3.8.0
3.8-dev
3.9-dev
…
(省略)
…
stackless-3.4.7
stackless-3.5.4
確認した中でpyenvで使用したいPythonバージョンを指定してインストールします。今回は3.8.0を指定しました。
$ pyenv install 3.8.0
インストールしたPythonバージョンがpyenvのバージョン一覧に追加されました。
$ pyenv versions
* system (set by /home/ec2-user/.pyenv/version)
3.8.0
pyenv global
で使用したいPythonバージョンに切り替えます。
$ pyenv global 3.8.0
pyenv上は3.8.0に切り替わりました。
$ pyenv versions
system
* 3.8.0 (set by /home/ec2-user/.pyenv/version)
しかし実際のPythonバージョンを確認すると3.6.10から変わっていません。
$ python --version
3.6.10
それもそのはずで、Cloud9ではpython
コマンドのAliasが既定で/usr/bin/python36
であるため、この指定を削除する必要がありました。
$ which python
alias python='python36'
/usr/bin/python36
この指定は~/.bashrc
内のalias python=python36
部分で既定で設定されているので、本部分をコメントアウトなどして削除します。
$ cat ~/.bashrc
# .bashrc
export PATH=$PATH:$HOME/.local/bin:$HOME/bin
# load nvm
export NVM_DIR="$HOME/.nvm"
[ "$BASH_VERSION" ] && npm() {
# hack: avoid slow npm sanity check in nvm
if [ "$*" == "config get prefix" ]; then which node | sed "s/bin\/node//";
else $(which npm) "$@"; fi
}
# [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm
rvm_silence_path_mismatch_check_flag=1 # prevent rvm complaints that nvm is first in PATH
unset npm # end hack
# User specific aliases and functions
alias python=python36
(省略)
既定のAliasの指定を削除したら、bashを再起動して変更を反映します。
$ exec $SHELL -l
python
コマンドのAliasがpyenvに変わりました。
$ which python
~/.pyenv/shims/python
Pythonバージョンも3.8.0に切り替わりました。
$ python --version
Python 3.8.0
pyenv global system
により既定のPythonバージョンに戻すこともできます。
$ pyenv global system
$ pyenv versions
* system (set by /home/ec2-user/.pyenv/version)
3.8.0
戻りました。(既定のAliasの指定を削除したことにより既定で実行されるバージョンは2系となっています)
$ python --version
Python 2.7.16
ディレクトリごとに異なるPythonバージョンを利用したい
ここまでpyenv global
によりPythonバージョンを切り替える方法を確認してきましたが、実際の開発においては、同じ環境で異なるPythonバージョンを同時に作業したい場合があります。
例えば下記のような同じ階層にあるdir1
およびdir2
ディレクトリからなる環境で、dir1
内ではPython3.8.0、dir2
内ではPython3.9-dev、という風にディレクトリごとに異なるバージョンを利用したいとします。
/home/ec2-user/environment/
| -- dir1 ←Python3.8.0
| -- dir2 ←Python3.9-dev
このような場合は、pyenv global
ではなく**pyenv local
**コマンドを使用してバージョンを指定した方が便利です。
pyenv globalとpyenv localの検証
pyenv globalの場合
pyenvで既定のPythonバージョンが選択されている状態(3.8.0と3.9-devはインストール済み)で、
$ cd ~/environment
$ python global system
$ pyenv versions
* system (set by /home/ec2-user/.pyenv/version)
3.8.0
3.9-dev
dir1
内でバージョンをpyenv global
により3.8.0に切り替えます。
$ cd ~/environment/dir1
$ pyenv global 3.8.0
$ python --version
3.8.0
dir2
内のPythonバージョンを確認すると、こちらも3.8.0となっていました。念の為bashを別プロセスで起動したとしても同じ結果となります。
$ cd ~/environment/dir2
$ python --version
3.8.0
- ドキュメント pyenv local
Sets a local application-specific Python version by writing the version name to a .python-version file in the current directory.
pyenv localの場合
次に、Pythonバージョンを既定に戻した状態で、dir1
内でバージョンをpyenv local
により3.8.0に切り替えてみます。
$ pyenv global system
$ cd ~/environment/dir1
$ pyenv local 3.8.0
$ python --version
3.8.0
またdir2
内のバージョンをpyenv local
により3.9-devに切り替えます。
$ cd ~/environment/dir2
$ pyenv local 3.9-dev
$ python --version
Python 3.9.0a4+
dir1
の方をもう一度確認すると3.8.0のままバージョンは保たれています。
$ cd ~/environment/dir1
$ python --version
Python 3.8.0
dir1
とdir2
の上位のディレクトリも既定のバージョンのまま保たれています。
$ cd ~/environment
$ python --version
Python 2.7.16
- ドキュメント pyenv global
Sets the global version of Python to be used in all shells by writing the version name to the ~/.pyenv/version file.
以上の検証の結果からも、ディレクトリごとに異なるPythonバージョンを使い分けたい場合は、それぞれのディレクトリでpyenv local
コマンドによりバージョンを指定するのが良いということが分かりました。
まとめ
ここまでの検証で確認した結果をまとめると以下のような手順となりました。
pyenv環境の初期設定
- pyenvをgitクローンします。
$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv
- 必要な設定がbash起動毎に行われるように
~/.bash_profile
に記述します。
$ echo 'export PATH="$HOME/.pyenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
~/.bashrc
内のalias python=python36
部分をコメントアウトします。- ここまでの設定をすぐに反映する場合はbashを再起動します。
$ exec $SHELL -l
ディレクトリごとの設定
- 現在のpyenv環境で利用可能なPythonバージョンを確認します。
$ pyenv versions
- 利用したいPythonバージョンがない場合はインストールします。
$ pyenv install <利用したいバージョン>
- ディレクトリに移動し、
pyenv local
で利用したいPythonバージョンを有効化します。
$ cd <dir>
$ pyenv local <利用したいバージョン>
おわりに
今まで環境を構築するごとにコマンドの意味をあまり理解せず手順に沿って機械的に打っていた節がありましたが、今回の検証により理解を深めることができました。