pyenvのインストール

pyenvのインストール手順のメモ

システムのpythonのバージョンを変更したり、モジュールの変更をしたりするとシステム上のスクリプトの動作に影響が出る場合があるので、pyenvで個別のpython環境を構築するのがベター。
さらに、virtualenvプラグインを使うと、同じpythonのバージョンでもそれぞれに別のモジュールをインストールできる、仮想環境を構築できる。

なお、pyenvはpythonをバイナリインストールできなくて、ソースからコンパイルするので、インストールにはそれなりに時間がかかる(RasPi2で1~2時間くらい?)。

インストール

準備

必要なモジュールをインストール

インストールに必要なモジュールをインストールする。

bluetoothを使用する場合

bluetoothを使用する場合は以下も必要

sudo apt install libbluetooth-dev libglib2.0-dev libboost-python-dev libboost-thread-dev

[!NOTE] 以前、 ubuntuの場合は以下と書いていたが、libbluetooth3-devlibbluetooth-devの別名定義だったので上のコマンドでOKのはず。

sudo apt install libbluetooth3-dev libglib2.0-dev libboost-python-dev libboost-thread-dev

pyenv本体とvirtualenvプラグインのインストール

pyenv本体とvirtualenvプラグインをインストール。
ついでにupdateプラグインも入れとく。

export PYENV_ROOT=/proj/.pyenv    #環境に合わせて修正してね
git clone https://github.com/yyuu/pyenv.git ${PYENV_ROOT}
git clone https://github.com/yyuu/pyenv-virtualenv.git ${PYENV_ROOT}/plugins/pyenv-virtualenv
git clone https://github.com/pyenv/pyenv-update.git ${PYENV_ROOT}/plugins/pyenv-update

~/.bashrcの編集

pyenvの設定のため、~/.bashrc に以下を追加。

# for pyenv
export PYENV_ROOT=/proj/.pyenv    #環境に合わせて修正してね
export PATH=$PYENV_ROOT/bin:$PATH
# 仮想環境名をプロンプトに表示しない場合は以下を有効化
# export VIRTUAL_ENV_DISABLE_PROMPT=1
eval "$(pyenv init --path)"          # pyenv 2.0以降で必要
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"

Raspbianでは以下も追加
numpyをimportしたとき、undefined symbol: PyFPE_jbuf でエラーになる対策。
参考: https://research.itplants.com/?p=2437

# Raspbian向け対策(numpyでundefined symbol: PyFPE_jbuf)
export PYTHON_CONFIGURE_OPTS="--enable-ipv6\
 --enable-unicode=ucs4\
 --enable-shared\
 --with-dbmliborder=bdb:gdbm\
 --with-system-expat\
 --with-system-ffi\
 --with-fpectl"

Ubuntuでは以下を追加しておく(デフォルトだとShared Library のimportでエラーになる)

export PYTHON_CONFIGURE_OPTS="\
 --enable-shared\
"

ここで設定を有効にするためにターミナルを開きなおす。

sudoでpyenv環境を実行するように設定する

sudoでpythonを実行すると、pyenvの設定に関係なくsystemのpythonが実行されてしまいます。
これを防ぐためには、/etc/sudoersDefaults secure_pathに以下のpathを追加します。

具体的には以下のように設定します。

# 変更前
Defaults  secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
    ↓
# 変更後
Defaults  secure_path="/proj/.pyenv/plugins/pyenv-virtualenv/shims:/proj/.pyenv/shims:/proj/.pyenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

設定

pyenvでインストールできるバージョンの一覧を表示

pyenv install --list 

pythonのインストール

pyenv install 3.6.4

・・・ 気長に待つ。 ・・・

デフォルトで使用するバージョンの設定

pyenv global 3.6.4

念のため指定したバージョンが実行されることを確認

python -V

仮想環境の構築

色々試したあとに、インストールしたモジュールをチャラにしたいときを考えて、仮想環境を構築しておく。
ここでは、python 3.6.4を使用して 仮想環境名 mypython を作成。

pyenv virtualenv 3.6.4 mypython

デフォルトをmypythonに変更する場合は以下を実行

pyenv global mypython

pipのバージョンアップ

「pipが古い~」と言われる前にバージョンアップ。ついでにsetuptoolsとwheelも。

pip install --upgrade pip setuptools wheel

[!IMPORTANT] ベース環境をバージョンアップしても、仮想環境に引き継がれないので、仮想環境毎に実行が必要。

ローカルバージョンの設定

ディレクトリ毎に使用するバージョンを指定するには(例えば、このディレクトリ下で作業するプロジェクトは3.4.1を使う、みたいな時)
そのディレクトリで以下のように実行する。
指定はそのディレクトリ直下だけでなく、その子ディレクトリ、孫ディレクトリ、・・・で有効。
shellを閉じても設定は残る。

pyenv local <バージョン名 or 仮想環境名>

一時的なバージョンの切り替え

そのshellだけ使用するバージョンを変更したい場合は、以下のよう実行する。

pyenv shell <バージョン名 or 仮想環境名>

別のターミナルでの実行には影響しない。

I2Cを使用する場合(RasPi)

RaspberryPi環境で、I2Cを使うためのsmbusモジュールは、通常 sudo apt install python3-smbus でインストールするが、これだとpyenv環境にインストールできない。
これはsmbus2をインストールして使用することで回避できる。 インストールは以下のように実行する。

pip install smbus2

ちなみに、pyenv 環境へのモジュールのインストールには sudo は不要。/usr 下へのインストールではないので。

で、プログラムソース側はsmbusのインストール部分を以下のように修正。

try:
    import smbus
except ImportError:
    import smbus2 as smbus

smbus2 だけにしても良いけど、smbus でも動作できるようにしておくのがベターかな。

pyenvのバージョンアップ

pythonの新しいバージョンがリリースされ、それをインストールしたい場合など、pyenvのバージョンアップが必要。
pyenv-updateをインストールしておけば(上記手順でインストール済み)、以下のコマンドですべてのプラグインを含めてバージョンアップしてくれる。

pyenv update

古い方法

pyenv-updateをインストールしていない場合は以下の手順でそれぞれのリポジトリをpullする。

cd ${PYENV_ROOT}
git pull

cd ${PYENV_ROOT}/plugins/pyenv-virtualenv
git pull

その他

ちょっとだけ使い方一覧。

システムのpythonを使いたい場合は以下のように実行

pyenv [global | local | shell] system

現在の状態で使用されるバージョン/仮想環境を確認

pyenv version

pyenvでインストールされているpythonのバージョン/仮想環境を確認

pyenv versions 

現在の状態で使用されるバージョンの先頭に「*」 が付く。

pyenv自体のバージョン確認

pyenv --version

pyenvで使用できるコマンドの確認

pyenv commands