猫野詩梨帳

かわいいはかしこい

【Python】Poetry で小さなパッケージをつくった

「空でないと保証された文字列」を扱いたいことがたまにあります。

そんなときのために自作パッケージ nonemptystr を作りました。

pip install nonemptystr でインストールできます。

github.com

ところで、このパッケージの作成・公開には Poetry というツールを使いました。

github.com

今回作成した nonemptystr パッケージはとても小さなパッケージです。ちょっと中身を見てみましょう。

リポジトリの中身

.gitignore, LICENSE

.gitignore と LICENSE は GitHub で新規リポジトリを作成するときに自動生成しました。ライセンスはオープンソースライセンスの MIT License を選択しています。

README.md

README です。GitHub リポジトリのトップページや PyPI プロジェクトのトップページにも表示されます。

簡単な使い方と API を載せています。今回は小さなパッケージのため、ドキュメントはこれ以外に用意しませんでした。

README の上部には「バッジ」と呼ばれているアイコンのようなものが表示されています。これは Shields.io などで作成できます。

pyproject.toml

pyproject.toml は PEP 518 で定義された新しいフォーマットのファイルで、今までの setup.py や setup.cfg に代わるものです。 Poetry ではこのファイルを利用して依存関係の管理やビルドを行います。

poetry init コマンドでは対話的にこのファイルを作成することもできます。

pyproject.toml ファイル内では以下のような項目を設定しています。

[tool.poetry] セクション

名前、バージョン、説明などの項目を設定しています。PyPI のプロジェクトページなどでも表示されます。

classifiers の項目は Classifiers · PyPI から選択しますが、License や Programming Language などは自動で設定されるようです。

[tool.poetry.dependencies] セクション

依存関係。 今回はサードパーティー製のライブラリを何も使っていませんが、Python のバージョンをここで指定しています。

手動で編集できるほか、poetry add コマンドなどで依存関係を追加すると自動で追加されます。

[tool.poetry.dev-dependencies] セクション

開発時のみ必要とする依存関係。 例えば black は、コードの自動フォーマットを行うためのツールです。

[build-system] セクション

デフォルトのままです。

pyproject.toml ファイルについての詳細は The pyproject.toml file | Documentation | Poetry - Python dependency management and packaging made easy. 1などを参照してください。

poetry.lock

Poetry が生成するロックファイルです。通常は依存関係をインストールしたときなどに自動で作成・更新されると思います。 npm の package-lock.json や Yarn の yarn.lock とかと同じようなものだと思います。

詳しくは Basic Usage | Documentation | Poetry - Python dependency management and packaging made easy.2 などを参照してください。

tasks.py

スクランナーとして Invoke を使用しています。

github.com

tasks.py というファイルにタスクを定義しておけば、 inv (タスク名)3 で起動することができるようになります。

今回は check というタスクを定義しておいて、コードのフォーマットやチェック、テストなどを通して行えるようにしておきました。

呼び出しているツールは以下の通りです。

  • isort: import 文の自動ソート
  • black: コードの自動フォーマット
  • flake8: コードのチェック
  • mypy: コードの型チェック
  • pytest: テストの実行

invoke.yaml

Invoke でタスクを走らせたときに pytest のカラー出力などが保たれるように設定をしています。特になくても問題ありません。

setup.cfg

pyproject.toml ファイルのおかげで setup.cfg は不要なのですが、ここでは flake8, isort, mypy の設定を記述するために使っています。

nonemptystr/

メインのソースコードが含まれています。

パッケージ名 (nonemptystr) と同じ名前のディレクトリにしているので、Poetry は自動でこのディレクトリを見つけてくれます。

もしディレクトリ名が特殊な場合は pyproject.toml の [tool.poetry] 内の packages で教えてあげる必要があります。

詳しくは The pyproject.toml file | Documentation | Poetry - Python dependency management and packaging made easy. 4などを参照してください。

また、py.typed は PEP 561 に準拠するためのもので、型ヒントがついたパッケージを公開するときに必要になります。 中身は空ですが、このファイルがないと mypy に文句を言われたりします。

詳しくは PEP 561 に準拠した型ヒントを含むパッケージの作り方 – ymyzk’s blog などを参照してください。

tests/

テストコードが含まれています。

パッケージの公開

実際に PyPI にパッケージを公開するまでの流れを見てみましょう。 なお、事前に PyPI のアカウントを作成しておく必要があります。

※ 当たり前ですが PyPI にパッケージを公開するということは全世界にパッケージを公開するということです。 公開したくないパッケージを不用意に公開しないように気を付けてください。

手元に nonemptystr リポジトリがあって、その中にいるとします。

まず仮想環境内でシェルを起動します。仮想環境がない場合は作成されます。

$ poetry shell

依存関係をインストールしていない場合はインストールします。 開発時のみの依存関係 (dev-dependencies) もインストールされます。

$ poetry install

ソースコードを作成・編集し終わったとします。 公開する前に、コードのフォーマットやチェック、テストを実行します。

$ inv check

問題なければ公開用にパッケージをビルドします。

$ poetry build

PyPI にパッケージを公開します。

$ poetry publish

ユーザーネームとパスワードの入力を求められた場合、PyPI のユーザーネームとパスワードを入力します。

これで完了です。ね、簡単でしょう?

まとめ

Poetry と pyproject.toml のおかげで簡単に Python パッケージを作成・公開できるようになりました。

また Poetry は活発に開発が行われており、たまによくわかんないエラーが出たりしてましたが比較的安定して動作するようになってきました。 依存関係のインストールも高速で便利です。

ぜひ Poetry 使っていきましょう。