poetry

先日、僕が入会しているオンラインサロンのメンバーの方に、「PipenvよりもPoetryの方がいい!」といったことをお聞きして、Poetryを知らなかったので調べて使ってみました。日本語に翻訳してくれている公式ドキュメントにそって進めていきます。

Poetryとは

PEP 518で提案されたpyproject.tomlによるパッケージ管理を導入したツールです。 pyproject.tomlrequirements.txtsetup.pysetup.cfgMANIFEST.inを置き換えることができます。Pipenvはrequirements.txtの置き換えしかできないので、いろんなファイルを置き換えることができて良いですね。また、Pipenvで使用するPipfileは独自規格で今後継続的に採用されるか不明なので、PipenvよりPoetryを使う方が良さそうです。

Poetryインストール

MacやLinuxでは以下コマンドでインストールします。

curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python

$HOME/.poetry/binにインストールされます。
Poetryを更新したいときは、以下コマンドを実行します。

poetry self update

Bash, Fish, Zshでの補完の有効化

僕はシェルにFishを使っていて、補完をサポートしてくるのでありがたいです。 公式ドキュメントには自分のシェルに合った次のコマンドどれかを使えばいいそうです。

# Bash
poetry completions bash > /etc/bash_completion.d/poetry.bash-completion

# Bash (macOS/Homebrew)
poetry completions bash > $(brew --prefix)/etc/bash_completion.d/poetry.bash-completion

# Fish
poetry completions fish > ~/.config/fish/completions/poetry.fish

# Zsh
poetry completions zsh > ~/.zfunc/_poetry

# Oh-My-Zsh
mkdir $ZSH/plugins/poetry
poetry completions zsh > $ZSH/plugins/poetry/_poetry

変更を効かせるために、シェルの再起動をしましょう。

プロジェクトのセットアップ

Poetryを試すためのプロジェクトを作成します。 次のコマンドで作成できます。poetry-demoと名付けています。

poetry new poetry-demo

するとpoetry-demoディレクトリが作成されます。

poetry-demo
├── pyproject.toml
├── README.rst
├── poetry_demo
│   └── __init__.py
└── tests
    ├── __init__.py
    └── test_poetry_demo.py

pyproject.tomlがプロジェクトの依存関係をまとめてくれています。中身はこのようになっています。

[tool.poetry]
name = "poetry-demo"
version = "0.1.0"
description = ""
authors = ["ユーザーネーム <ユーザーのEmail>"]

[tool.poetry.dependencies]
python = "^3.8"

[tool.poetry.dev-dependencies]
pytest = "^5.2"

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

python = "^3.8"^3.8はバージョンの制約を表していて、Pythonのバージョンが3.8以上という意味です。

次に静的解析ができるflake8をインストールします。 addコマンドでインストールできます。

poetry add flake8

するとターミナルに以下表示がされます。

Creating virtualenv poetry-demo-nVKjKWA1-py3.8 in /Users/ユーザーネーム/Library/Caches/pypoetry/virtualenvs
Using version ^3.7.9 for flake8

Updating dependencies
Resolving dependencies... (2.4s)

Writing lock file


Package operations: 14 installs, 0 updates, 0 removals

  - Installing pyparsing (2.4.6)
  - Installing six (1.14.0)
  - Installing attrs (19.3.0)
  - Installing entrypoints (0.3)
  - Installing mccabe (0.6.1)
  - Installing more-itertools (8.2.0)
  - Installing packaging (20.3)
  - Installing pluggy (0.13.1)
  - Installing py (1.8.1)
  - Installing pycodestyle (2.5.0)
  - Installing pyflakes (2.1.1)
  - Installing wcwidth (0.1.9)
  - Installing flake8 (3.7.9)
  - Installing pytest (5.4.1)

pyproject.tomlを再度確認すると

[tool.poetry]
name = "poetry-demo"
version = "0.1.0"
description = ""
authors = ["ユーザーネーム <ユーザーのEmail>"]

[tool.poetry.dependencies]
python = "^3.8"
flake8 = "^3.7.9"

[tool.poetry.dev-dependencies]
pytest = "^5.2"

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

インストールできていることが確認できます。

インストールしたパッケージを使う

Pythonコードを静的解析したの記事で使ったtest.pyと同じ内容のファイルをpoetry-demo/poetry-demo/配下に作成します。
test.py

def example(num_a,num_b,num_c,num_d,num_e,num_f,num_g,num_h):
    print(num_a+num_b+num_c+num_d+num_e+num_f+num_g+num_h)
num_a,num_b,num_c,num_d,num_e,num_f,num_g,num_h = 1,   2,  3,  4, 5,  6,  7,   8
example(   num_a,     num_b,      num_c, num_d,num_e,   num_f,  num_g,   num_h  )

このファイルをflake8を使って静的解析します。 プロジェクトのルートディレクトリで以下コマンドを実行します。

poetry run flake8 poetry_demo/test.py

すると、ターミナルに以下表示がされます。

test.py:1:18: E231 missing whitespace after ','
test.py:1:24: E231 missing whitespace after ','
test.py:1:30: E231 missing whitespace after ','
test.py:1:36: E231 missing whitespace after ','
test.py:1:42: E231 missing whitespace after ','
test.py:1:48: E231 missing whitespace after ','
test.py:1:54: E231 missing whitespace after ','
test.py:3:1: E305 expected 2 blank lines after class or function definition, found 0
test.py:3:6: E231 missing whitespace after ','
test.py:3:12: E231 missing whitespace after ','
test.py:3:18: E231 missing whitespace after ','
test.py:3:24: E231 missing whitespace after ','
test.py:3:30: E231 missing whitespace after ','
test.py:3:36: E231 missing whitespace after ','
test.py:3:42: E231 missing whitespace after ','
test.py:3:80: E501 line too long (80 > 79 characters)
test.py:4:9: E201 whitespace after '('
test.py:4:47: E231 missing whitespace after ','
test.py:4:80: E501 line too long (81 > 79 characters)
test.py:4:80: E202 whitespace before ')'

poetry runを使うことで、インストールしたパッケージがスクリプトから使うことが保証されて、実行をすることができます。

まとめ

調べているときに、他のパッケージ管理ツールとしてPyflowというものもありましたが、Rustで作られていて、エラーが吐き出されたときにある程度Rustを理解していないと使えないみたいなので、今後はPipenv, PyflowよりもPoetryを使う方が良さそうです。 速度に関してもPipenvはpipfile.lockの生成がとても時間がかかるけど、Poetryは非常に高速らしいので、Poetry一択ですね。