え、まだsetup.py使ってるの? pyproject.tomlとsetup.cfgで宣言的パッケージング


というタイトルは煽りで、個人的にはまだ時期尚早な感じもあると思いますが。
いずれはこちらが標準になるでしょうし。なんだかんだで結構苦労したので、setuptoolsを使うがsetup.pyは使わずにpyproject.tomlsetup.cfgを使ってパッケージを作る方法をメモしておきます。

pyproject.tomlって?

ざっくりいうと、みんなsetup.pyを書いたり動かしたりするのに疲れたのだと思います。

pyproject.tomlについて規定しているPEP 518では、setup.py自体を動かすために必要な依存パッケージを定義する標準的な方法がないことがモチベーションとされています。個人的には、setup_requirements.txtでも用意すればいいのでは、と感じましたが。まぁ、みんなsetup.pyに疲れたのだと思います。

いずれにせよ、setuptoolsの他にも、poetryflitなどのビルドツールもあるらしく、今はsetuptoolsがデファクトスタンダードだけど、ずっと主流とは限らないよねー、標準的な方法を作っておきたいねー、ていうか、setup.pyに疲れたんだよ、ということだと思います。

pyproject.tomlsetuptoolsを使うには

pyproject.tomlを以下のようにします。

pyproject.toml
[build-system]
requires = ["wheel", "setuptools"]
build-backend = "setuptools.build_meta"

setup.cfgを書こう

続いて、setup.pyの代わりにsetup.cfgを作ります。
ぶっちゃけこれは、setuptools.setup()の引数を設定ファイルの形式にしただけですが、[metadata][options]に項目を分けて書かなければいけません。

setuptools公式ドキュメントのQuick StartConfiguring setup() using setup.cfg filesに詳細が載っています。

参考までに、私の関わっているプロジェクトsetup.cfgを以下に示します。

setup.cfg
[metadata]
name = braket-backend-blueqat
version = 0.0.1-pre
description = Braket backend for blueqat
long_description = file: README.md
long_description_content_type = text/markdown
license = Apache-2.0
author = gyu-don
author_email = [email protected]
classifiers =
    Development Status :: 3 - Alpha
    License :: OSI Approved :: Apache Software License
    Programming Language :: Python :: 3.7
    Programming Language :: Python :: 3.8

[options]
packages = find:
install_requires =
    blueqat >= 0.4.2
    amazon-braket-sdk >= 1.5.13

ほとんどsetup.pyと同じですね。

なお、attr:file:など、いくつか、設定を書く際に便利なものがあります。setup.pyREADME.mdの中身を読んでいたのとかが詳細はやはりドキュメントに書かれています。

なお、versionの指定にattr:を使うことも考えたのですが、その場合、一旦自分自身をimportすることになるので、ビルド環境に自分自身のinstall_requiresが必要となり、それは面倒なのでやめました。
代わりにGitHub Actionsを使ってsetup.cfgをもとに_version.pyを更新することで解決しています。

ビルドをしよう

python -m build で、忌々しいsetup.pyなしでビルドができます。

No module named build というエラーが出る場合は pip install buildをしてから、再度python -m buildをしてください。

setup.cfgがあればsetup.pyも簡単に書ける

せっかくsetup.pyを消し去ったのになぜ、、、という気もするのですが。もしsetup.pyも欲しい場合、setup.cfgがあればsetup.pyは以下だけで構いません。

setup.py
from setuptools import setup
setup()

なお、setup.pyが必要となる場面のひとつに、editableなインストールがあります。pip install .setup.pyがなくてもできるのですが、pip install -e .setup.pyがないと対応していないようです。

いかがでしたか

よきPythonライフを!