LoginSignup
16
16

More than 1 year has passed since last update.

pyenv によるPythonインストールと落とし穴 (Mac, Ubuntu, CentOS)

Last updated at Posted at 2022-10-23

pyenv

pyenv はさまざまなバージョン・実装の Python のインストールとバージョン切り替えを行うための shell scripts 製のソフトウェアです.
Python はソースのダウンロードからビルド・インストールまでを自動で行ってくれる一方, 一部のOSではコンパイルに必要なライブラリのバージョン不整合でインストールに失敗してしまうケースもあります(CentOS7, Debian7など)
pyenv の使い方とインストールにハマったときの対処を記述します.

とりあえずチートシート

  • pyenv versions -- インストール済みのバージョン一覧
  • pyenv shell <version> -- シェルセッションでバージョン切り替え
  • pyenv local <version> -- 現在のディレクトリ以下でバージョン切り替え
  • pyenv global <version> -- グローバルのバージョンの切り替え
  • pyenv install --list -- インストール可能なバージョン一覧
  • pyenv install <version> -- python のインストール
  • pyenv which python -- pythonのフルパスの確認

使用例

$ pyenv install --list | grep 3.10
  3.10.0
  3.10-dev
  3.10.1
  3.10.2
  3.10.3
  3.10.4
  3.10.5
  3.10.6
  3.10.7
  mambaforge-4.10.3-10
  miniconda-3.10.1
  miniconda3-3.10.1
  miniforge3-4.10.3-10

$ pyenv install 3.10.7
python-build: use openssl@1.1 from homebrew
python-build: use readline from homebrew
Downloading Python-3.10.7.tar.xz...
...

$ pyenv versions
  system
  3.9.14
* 3.10.7 (set by ~/.pyenv/version)

$ pyenv global 3.10.7

pyenv のインストール

Linux

git clone https://github.com/pyenv/pyenv.git ~/.pyenv
cd ~/.pyenv && src/configure && make -C src

二行目は高速化のために Bash拡張のコンパイルをしています. 環境によっては失敗しますが, その場合でも pyenv は正常に動作します

MacOS

brew update
brew install pyenv

(OS共通) ログインシェルの設定ファイルに追記

  • Bash
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc
  • Zsh
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
echo 'eval "$(pyenv init -)"' >> ~/.zshrc

python ランタイムのインストール

インストール可能な Python バージョンの確認

  • pyenv install --list

各Pythonバージョンのインストール

  • pyenv install <version>
    • python-build により, Python の各バージョンのソースダウンロード・ビルド・インストールをしてくれる
    • -v オプションで詳細表示するとコンパイルログが見れる
    • マシンの環境によってはビルド失敗・Warningがでる場合がある. その場合は下記のように必要なパッケージを入れてインストールしてください.

ビルド失敗例: Python3.10 のビルドには OpenSSL1.1.1 以降が必須 なので, CentOS7 や Debian7 (OpenSSL 1.0.2) ではビルドに失敗する.

ERROR: The Python ssl extension was not compiled. Missing the OpenSSL lib?

Please consult to the Wiki page to fix the problem.
https://github.com/pyenv/pyenv/wiki/Common-build-problems


BUILD FAILED (CentOS Linux 7 using python-build 2.3.5-2-g03a5d65)

インストールに失敗するとき

Python のビルドに必要なパッケージのインストールをする.

Debian系(Ubuntu など)
sudo apt update
sudo apt install build-essential libbz2-dev libdb-dev \
  libreadline-dev libffi-dev libgdbm-dev liblzma-dev \
  libncursesw5-dev libsqlite3-dev libssl-dev \
  zlib1g-dev uuid-dev tk-dev
CentOS
sudo yum groupinstall "development tools"
sudo yum install bzip2-devel gdbm-devel libffi-devel \
  libuuid-devel ncurses-devel openssl-devel readline-devel \
  sqlite-devel xz-devel zlib-devel tk-devel
CentOS7

Pyhton3.10 以降のコンパイルには OpenSSL1.1以降のインストールが必要です. 手間に感じる場合はコンテナイメージ内での開発も視野に入れると良いでしょう.

OpenSSL1.1.1 のインストールと penv による Python3.10.x のインストール

a. OpenSSL のインストールに必要なパッケージのインストール

sudo yum install -y zlib-devel perl-core make gcc

b. OpenSSL のソースダウンロードとインストール

sudo curl https://www.openssl.org/source/openssl-1.1.1.tar.gz -o /usr/local/src/openssl-1.1.1.tar.gz
cd /usr/local/src
sudo tar xvzf openssl-1.1.1.tar.gz
cd openssl-1.1.1/
./config --prefix=/usr/local/openssl-1.1.1 --openssldir=/usr/local/openssl-1.1.1/ssl
make
sudo make install

c. OpenSSLを共有ライブラリに追加する

sudo echo "/usr/local/openssl-1.1.1/lib" > /etc/ld.so.conf.d/openssl-1.1.1.conf
sudo /sbin/ldconfig

d. pyenv install する際は PYTHON_CONFIGURE_OPTS で 上記でインストールしたOpenSSLを指定する.
Python 3.10.8 をインストールする場合:

env PYTHON_CONFIGURE_OPTS="--with-openssl=/usr/local/openssl-1.1.1 --with-ssl-default-suites=openssl" pyenv install 3.10.8

python バージョン切り替え

インストール済みのバージョン確認

  • pyenv versions

バージョン切り替え

  • pyenv shell <version> -- 現在のシェルのセッションのみでバージョン切り替え
  • pyenv local <version> -- カレントディレクトリ(および配下)にいるときに, 自動的にそのバージョンに切り替
  • pyenv global <version> -- ユーザーアカウントに対してグローバルにバージョン切り替え

また, <version> に複数の値を渡すと, 複数のバージョンが実行可能になります(python3.Xのように指定する. pythonを実行した場合のバージョンは左に書いたものから優先される). これは, tox などで複数のバージョンでテストを実行する際に役立ちます.

pyenv 自体のアップデート

Linux

~/.pyenvを削除して再度インストールでもよいですが, pyenv-update というプラグインを使う方法もあります.

  • pyenv-updateのインストール (pyenvはインストール済みであることが前提)
git clone https://github.com/pyenv/pyenv-update.git $(pyenv root)/plugins/pyenv-update
  • アップデート
    • pyenv update

Mac

homebrew でインストールした場合:

  • brew update && brew upgrade pyenv

pyenv のしくみ

pyenv は次の順序でバージョンを見つけることで, バージョン切り替え時の shell, local, global の機能を実現しています.

  1. 環境変数PYENV_VERSIONが存在すれば現在のシェルセッションでそのバージョンの Python を使用する.
    pyenv shell コマンドはこの環境変数を設定する.
  2. カレントディレクトリからルートディレクトリまでをたどり, .python-version ファイルが存在すればそのバージョンを使用する.
    pyenv local コマンドはカレントディレクトリにこの設定ファイルを作成する.
  3. $(pyenv root)/version に記載されたバージョンのPythonを使用する.
    pyenv global コマンドはこのファイルのバージョンを書き換える.

そして, pyenv は次のようにバージョン切り替えを実現しています.

  • pythonpip などの実行時には pyenv 初期化時に PATH に追加された$(pyenv root)/shims に置かれたコマンドが呼ばれる.
  • shims 内のコマンドは上記の方法でバージョンを検知し, インストールしたバイナリへリダイレクトする
    • which python をするとこのshimsディレクトリ内のバイナリのパスを指すが, インストールした実体へのパスは pyenv which python で知ることができる.
16
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
16