ヴェズルフェルニルの研究ノート

座右の銘「ただ一人犀の角のように歩め」的な研究活動ノート

【Python】anyenv + pyenv + Poetryによる仮想環境構築

日常的にPythonでプログラミングしているが、開発対象のプログラムやプロジェクトによって使用するPythonのバージョンを変えなればならないケースが多いので、ほとんどの人がそうしているだろうが、私もPythonでの開発は仮想環境でしかやらない。

Pythonの仮想環境ツールとして、最初の頃はpipenvを利用していたがいまはPoetryを利用している。また、複数の言語を使ってプログラミングするので、言語バージョン管理ツールとしてanyenvとpyenvも併用している。

python-poetry.org

github.com

github.com

自分の備忘録を兼ねて、anyenv + pyenv + Poetryを利用してPython仮想環境を構築する手順を要点だけに絞って本記事に書いておく。いずれのツールもリファレンス的記事はたくさん存在するので、各ツールの詳しい使い方はそれらの記事に譲る。

anyenvのインストール

$ git clone https://github.com/anyenv/anyenv ~/.anyenv
% brew install anyenv

anyenvのコマンドパスを設定

Ubuntu

$ echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(anyenv init -)"' >> ~/.bashrc
% echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.zshrc
% echo 'eval "$(anyenv init -)"' >> ~/.zshrc

Mac

$ echo 'eval "$(anyenv init -)"' >> ~/.bashrc
% echo 'eval "$(anyenv init -)"' >> ~/.zshrc

anyenvの初期化とプラグインの追加

$ exec $SHELL -l
$ anyenv --version
$ anyenv install --init
Manifest directory doesn't exist: /home/USERNAME/.config/anyenv/anyenv-install
Do you want to checkout https://github.com/anyenv/anyenv-install.git? [y/N]: y
Cloning https://github.com/anyenv/anyenv-install.git master to /home/LOGNAME/.config/anyenv/anyenv-install...
Cloning into '/home/USERNAME/.config/anyenv/anyenv-install'...
....    ....
....    ....

Completed!
$ mkdir -p $(anyenv root)/plugins
$ git clone https://github.com/znz/anyenv-update.git $(anyenv root)/plugins/anyenv-update
$ git clone https://github.com/znz/anyenv-git.git $(anyenv root)/plugins/anyenv-git
$ anyenv commands
commands
completions
envs
git
global
help
init
install
local
root
uninstall
update
--version
version
versions

anyenvによるpyenvのインストール

$ anyenv install --list
  Renv
  crenv
  denv
  erlenv
  exenv
  goenv
  hsenv
  jenv
  jlenv
  kubectlenv
  luaenv
  nodenv
  phpenv
  plenv
  pyenv
  rbenv
  sbtenv
  scalaenv
  swiftenv
  tfenv
$ anyenv install pyenv
$ exec $SHELL -l
$ pyenv --version

pyenvによるPythonのインストール

% pyenv install --list
Available versions:
  2.1.3
  2.2.3
  2.3.7
  2.4.0
  2.4.1
  2.4.2
  2.4.3
  2.4.4
  2.4.5
  2.4.6
  2.5.0
  2.5.1
  2.5.2
  2.5.3
  2.5.4
  2.5.5
  2.5.6
  2.6.0
  2.6.1
  2.6.2
  2.6.3
  2.6.4
  2.6.5
  2.6.6
  2.6.7
  2.6.8
  2.6.9
  2.7.0
  2.7-dev
  2.7.1
  2.7.2
  2.7.3
  2.7.4
  2.7.5
  2.7.6
  2.7.7
  2.7.8
  2.7.9
  2.7.10
  2.7.11
  2.7.12
  2.7.13
  2.7.14
  2.7.15
  2.7.16
  2.7.17
  2.7.18
  3.0.1
  3.1.0
  3.1.1
  3.1.2
  3.1.3
  3.1.4
  3.1.5
  3.2.0
  3.2.1
  3.2.2
  3.2.3
  3.2.4
  3.2.5
  3.2.6
  3.3.0
  3.3.1
  3.3.2
  3.3.3
  3.3.4
  3.3.5
  3.3.6
  3.3.7
  3.4.0
  3.4-dev
  3.4.1
  3.4.2
  3.4.3
  3.4.4
  3.4.5
  3.4.6
  3.4.7
  3.4.8
  3.4.9
  3.4.10
  3.5.0
  3.5-dev
  3.5.1
  3.5.2
  3.5.3
  3.5.4
  3.5.5
  3.5.6
  3.5.7
  3.5.8
  3.5.9
  3.5.10
  3.6.0
  3.6-dev
  3.6.1
  3.6.2
  3.6.3
  3.6.4
  3.6.5
  3.6.6
  3.6.7
  3.6.8
  3.6.9
  3.6.10
  3.6.11
  3.6.12
  3.6.13
  3.6.14
  3.6.15
  3.7.0
  3.7-dev
  3.7.1
  3.7.2
  3.7.3
  3.7.4
  3.7.5
  3.7.6
  3.7.7
  3.7.8
  3.7.9
  3.7.10
  3.7.11
  3.7.12
  3.7.13
  3.7.14
  3.7.15
  3.7.16
  3.7.17
  3.8.0
  3.8-dev
  3.8.1
  3.8.2
  3.8.3
  3.8.4
  3.8.5
  3.8.6
  3.8.7
  3.8.8
  3.8.9
  3.8.10
  3.8.11
  3.8.12
  3.8.13
  3.8.14
  3.8.15
  3.8.16
  3.8.17
  3.9.0
  3.9-dev
  3.9.1
  3.9.2
  3.9.4
  3.9.5
  3.9.6
  3.9.7
  3.9.8
  3.9.9
  3.9.10
  3.9.11
  3.9.12
  3.9.13
  3.9.14
  3.9.15
  3.9.16
  3.9.17
  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
  3.10.8
  3.10.9
  3.10.10
  3.10.11
  3.10.12
  3.11.0
  3.11-dev
  3.11.1
  3.11.2
  3.11.3
  3.11.4
  3.12.0b4
  3.12-dev
  3.13-dev
  ....    ....
  ....    ....
  ....    ....
  ....    ....
  ....    ....
  ....    ....
  ....    ....
  ....    ....

使用する予定のバージョンをインストールしておく。

$ pyenv install 3.8.17
$ pyenv install 3.9.17
$ pyenv install 3.10.12
$ pyenv install 3.11.4
$ pyenv rehash
$ pyenv versions
* system (set by /home/USERNAME/.anyenv/envs/pyenv/version)
  3.8.17
  3.9.17
  3.10.12
  3.11.4

pyenvによるPythonインストール時の補足情報

Ubuntuで、anyenvによってPythonをインストールするときに、以下のようなエラーが表示されることがある。

$ pyenv install 3.8.17
....    ....
....    ....
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/USERNAME/.anyenv/envs/pyenv/versions/3.8.17/lib/python3.8/bz2.py", line 19, in <module>
    from _bz2 import BZ2Compressor, BZ2Decompressor
ModuleNotFoundError: No module named '_bz2'
WARNING: The Python bz2 extension was not compiled. Missing the bzip2 lib?
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'readline'
WARNING: The Python readline extension was not compiled. Missing the GNU readline lib?
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/USERNAME/.anyenv/envs/pyenv/versions/3.8.17/lib/python3.8/ssl.py", line 98, in <module>
    import _ssl             # if we can't import it, let the error propagate
ModuleNotFoundError: No module named '_ssl'
ERROR: The Python ssl extension was not compiled. Missing the OpenSSL lib?
....    ....
....    ....

その場合は、以下のコマンドを実行すれば解決できる。

$ sudo apt install -y libbz2-dev libreadline-dev libssl-dev
$ pyenv install 3.8.17

Ubuntuで、anyenvによってPythonをインストールするときに、以下のような警告が表示されることがある。

$ pyenv install 3.8.17
....    ....
....    ....
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/USERNAME/.anyenv/envs/pyenv/versions/3.8.17/lib/python3.8/sqlite3/__init__.py", line 23, in <module>
    from sqlite3.dbapi2 import *
  File "/home/USERNAME/anyenv/envs/pyenv/versions/3.8.17/lib/python3.8/sqlite3/dbapi2.py", line 27, in <module>
    from _sqlite3 import *
ModuleNotFoundError: No module named '_sqlite3'
WARNING: The Python sqlite3 extension was not compiled. Missing the SQLite3 lib?
Installed Python-3.8.17 to /home/USERNAME/.anyenv/envs/pyenv/versions/3.8.17

その場合は、以下のコマンドを実行すれば解決できる。

$ pyenv uninstall 3.8.17
$ sudo apt install -y libsqlite3-dev
$ pyenv install 3.8.17

UbuntuまたはMacで、anyenvによってPythonをインストールするときに、以下のような警告が表示されることがある。

$ pyenv install 3.8.17
....    ....
....    ....
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/USERNAME/.anyenv/envs/pyenv/versions/3.8.17/lib/python3.8/tkinter/__init__.py", line 36, in <module>
    import _tkinter # If this fails your Python may not be configured for Tk
ModuleNotFoundError: No module named '_tkinter'
WARNING: The Python tkinter extension was not compiled and GUI subsystem has been detected. Missing the Tk toolkit?
Installed Python-3.8.17 to /home/USERNAME/.ayenv/envs/pyenv/versions/3.8.17

その場合は、以下のコマンドを実行すれば解決できる。

$ pyenv uninstall 3.8.17
$ sudo apt install -y python3-tk tk-dev
$ pyenv install 3.8.17
% pyenv uninstall 3.8.17
% brew install python-tk
% pyenv install 3.8.17

UbuntuまたはMacでanyenvによってPythonをインストールするときに、下のような警告が表示されることがある。

$ pyenv install 3.8.17
....    ....
....    ....
python-build: use zlib from xcode sdk
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/USERNAME/.anyenv/envs/pyenv/versions/3.8.17/lib/python3.8/lzma.py", line 27, in <module>
    from _lzma import *
ModuleNotFoundError: No module named '_lzma'
WARNING: The Python lzma extension was not compiled. Missing the lzma lib?
Installed Python-3.8.17 to /home/USERNAME/.anyenv/envs/pyenv/versions/3.8.17

その場合は、以下のコマンドを実行すれば解決できる。

$ pyenv uninstall 3.8.17
$ sudo apt install -y liblzma-dev
$ pyenv install 3.8.17
% pyenv uninstall 3.8.17
% brew install xz
% pyenv install 3.8.17

Pythonバージョンの設定

グローバルなバージョンを設定

$ pyenv global 3.8.17
$ cd
$ python --version
Python 3.8.17

プロジェクトのローカルバージョンを設定

$ cd PROJECT_DIR
$ pyenv local 3.8.17
$ python --version
Python 3.8.17

Poetryのインストール

$ curl -sSL https://install.python-poetry.org | python3 -
$ echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
$ source ~/.bashrc
$ poetry --version
Poetry (version 1.5.1)
% brew install poetry
% poetry --version
Poetry (version 1.5.1)

プロジェクトディレクトリ内に仮想環境を構築するように設定

$ poetry config virtualenvs.in-project true
$ poetry config --list
....    ....
virtualenvs.in-project = true
....    ....

pyenv + PoetryによるPython仮想環境構築

プロジェクトの作成・初期化

$ mkdir PROJECT_DIR
$ cd PROJECT_DIR
$ pyenv local 3.10.12
$ python --vresion
Python 3.10.12
$ poetry init
Configuration file exists at /Users/LOGNAME/Library/Preferences/pypoetry, reusing this directory.

Consider moving TOML configuration files to /Users/LOGNAME/Library/Application Support/pypoetry, as support for the legacy directory will be removed in an upcoming release.

This command will guide you through creating your pyproject.toml config.

Package name [project_dir]:
Version [0.1.0]:
Description []:
Author [vedfolnir-k9 <vedfolnir@ketus-ix.work>, n to skip]:
License []:
Compatible Python versions [^3.11]:  >=3.8,<3.11

Would you like to define your main dependencies interactively? (yes/no) [yes] no
Would you like to define your development dependencies interactively? (yes/no) [yes] no
Generated file

[tool.poetry]
name = "project-dir"
version = "0.1.0"
description = ""
authors = ["vedfolnir-k9 <vedfolnir@ketus-ix.work>"]
readme = "README.md"
packages = [{include = "project_dir"}]

[tool.poetry.dependencies]
python = ">=3.8,<3.11"


[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"


Do you confirm generation? (yes/no) [yes]

プロンプトCompatible Python versions [^3.11]:に対する入力は、以下のような意味になる。

  • ^3.11

3.11 ≦ プログラムのPython依存バージョン < 4.0

  • >=3.8,<3.11

3.8 ≦ プログラムのPython依存バージョン ≦ 3.10

仮想環境の初期化

$ poetry install
Configuration file exists at /Users/LOGNAME/Library/Preferences/pypoetry, reusing this directory.

Consider moving TOML configuration files to /Users/LOGNAME/Library/Application Support/pypoetry, as support for the legacy directory will be removed in an upcoming release.
The currently activated Python version 3.11.4 is not supported by the project (>=3.8,<3.11).
Trying to find and use a compatible version.
Using python3 (3.10.12)
Creating virtualenv project-dir2 in /Users/LOGNAME/PROJECT_DIR/.venv
Updating dependencies
Resolving dependencies... (0.1s)

Writing lock file
/Users/LOGNAME/PROJECT_DIR/project_dir does not contain any element

Poetryでのパッケージ管理

パッケージの追加

$ poerty add PACKAGE_NAME

パッケージの削除

$ poerty remove PACKAGE_NAME

開発用パッケージの追加

$ poerty add --dev PACKAGE_NAME

開発用パッケージの削除

$ poerty remove --dev PACKAGE_NAME

PoetryによるPythonプログラム実行

仮想環境によって直接プログラムを実行

$ poetry run python PROGRAM.py

仮想環境を起動して、プログラムを実行

$ poetry shell
$ python PROGRAM.py

補足情報

requirements.txtが存在する既存のPythonプログラムを利用する場合、Poetryによるプロジェクトディレクトリの作成・初期化後に以下のコマンドを実行するとすべての依存パッケージをインストールできる。

$ cat requirements.txt | xargs poetry add

【追記】〔2023-08-19〕

上には、pyenvによるPythonのインストール時に遭遇するエラーや警告の対処方法について個別に書いたが、これを一括で回避する方法がpyenvのサイトに掲載されていた。

コマンドpyenv install PYTHON_VERSIONを実行する前に、以下のコマンドによってPythonの依存バッケージをインストールしておけば良い。

$ sudo apt install build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev curl \
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
% brew install openssl readline sqlite3 xz zlib tcl-tk

【参照リンク】

github.com