【Python】パッケージ配布 ~ pyproject.tomlによる作成方法 ~

■ はじめに

https://dk521123.hatenablog.com/entry/2024/03/19/000000

の続き。

今回は、Pythonのパッケージ配布において、
pyproject.tomlによる作成方法について扱う。
 => ってゆーかーめちゃ簡単だった、、、

目次

【1】今回使用するパッケージ構成
 1)フォルダ構成例
【2】pyproject.toml
 1)サンプル
 2)パッケージ作成
【3】補足:「py-modules = []」について
 1)エラーメッセージ「error: Multiple top-level packages discovered in a flat-layout」
 2)別の解決案を考える
 3)別案「1. set up custom discovery」について
 4)別案「2. use a `src-layout`」について

【1】今回使用するパッケージ構成

* 以下の関連記事と同じものを使う
 => ただし、setup.py の代わりに「pyproject.toml」を配置

パッケージ配布 ~ setup.pyによる作成方法 ~
https://dk521123.hatenablog.com/entry/2024/03/19/000000

1)フォルダ構成例

├─ hello_package # パッケージ
│   ├─ world_sub_package # サブパッケージ(Options)
│   │   ├─ __init__.py
│   │   └─ world.py # サブモジュール
│   ├─ __init__.py
│   └─ hello.py # モジュール
├─ main.py # モジュール動作確認用プログラム(Options)
└─ pyproject.toml # ★今回のテーマ★

【2】pyproject.toml

* setup.py の 代わりに「pyproject.toml」で、TOML形式で書ける
 => TOML については、以下の関連記事を参照のこと

TOML
https://dk521123.hatenablog.com/entry/2023/04/25/103533

* 細かいことをやりたい場合は、以下の公式ドキュメントを参考にやっていければ、、、

https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#a-full-example

1)サンプル

[project]
name = "hello_package"
version = "1.0.0"
authors = [{ name="Your-name", email="your-name@xxx.com" }]
description = "This is a sample"
requires-python = ">=3.10"

# 『【3】補足:「py-modules = []」について』参照
[tool.setuptools]
py-modules = []

2)パッケージ作成

https://dk521123.hatenablog.com/entry/2024/03/19/000000

と同じコマンドで実行して作成できる

コマンド例

# Step1: build パッケージをインストールする
python -m pip install build

# Step2: パッケージ作成
python -m build

【3】補足:「py-modules = []」について

* 以下の記述がないと、エラーになる
~~~~
[tool.setuptools]
py-modules = []
~~~~
* ちなみに、以下のサイトを参考にした

https://stackoverflow.com/questions/72294299/multiple-top-level-packages-discovered-in-a-flat-layout

1)エラーメッセージ「error: Multiple top-level packages discovered in a flat-layout」

$ python -m build
* Creating isolated environment: venv+pip...
* Installing packages in isolated environment:
  - setuptools >= 40.8.0
* Getting build dependencies for sdist...
★ここ
error: Multiple top-level packages discovered in a flat-layout: [...., 'hello_package'].

To avoid accidental inclusion of unwanted files or directories,
setuptools will not proceed with this build.

If you are trying to create a single distribution with multiple packages
on purpose, you should not rely on automatic discovery.
Instead, consider the following options:

1. set up custom discovery (`find` directive with `include` or `exclude`)
2. use a `src-layout`
3. explicitly set `py_modules` or `packages` with a list of names

To find more information, look for "package discovery" on setuptools docs.

ERROR Backend subprocess exited when trying to invoke get_requires_for_build_sdist

2)別の解決案を考える

* エラーメッセージに親切に書いてある。
~~~~~
1. set up custom discovery (`find` directive with `include` or `exclude`)
2. use a `src-layout` << 後述
3. explicitly set `py_modules` or `packages` with a list of names << 今回取った解決案
~~~~~

3)別案「1. set up custom discovery」について

[tool.setuptools.packages.find]
where = ["."]  # list of folders that contain the packages (["."] by default)
include = ["hello_package"]  # package names should match these glob patterns (["*"] by default)
exclude = []  # exclude packages matching these glob patterns (empty by default)
namespaces = false  # to disable scanning PEP 420 namespaces (true by default)

4)別案「2. use a src-layout」について

* 以下のサイトに詳しく書いてある
 => フォルダ構成を変えていい段階であれば、こっちの方がいいかも。

https://qiita.com/ieiringoo/items/4bef4fc9975803b08671

フォルダ構成「src-layout」

├── main.py
├── pyproject.toml
├── src/
│    └── hello_package/
│       ├── __init__.py
│       ├── hello.py
│       └── hello_package/ ...
...

pyproject.toml

[tool.setuptools]
package-dir = {"" = "src"}

【補足】src-layout vs flat-layout

* 以下も一読しておくといいかも。

https://packaging.python.org/en/latest/discussions/src-layout-vs-flat-layout/

参考文献

https://nikkie-ftnext.hatenablog.com/entry/pyproject-toml-project-keys-and-examples
https://nikkie-ftnext.hatenablog.com/entry/why-dont-you-write-pyproject-toml-instead-of-setup-py
https://qiita.com/propella/items/5cd89caee6379920d889

関連記事

パッケージ配布 ~ setup.pyによる作成方法 ~
https://dk521123.hatenablog.com/entry/2024/03/19/000000
パッケージ配布 ~ setuptoolsあれこれ ~
https://dk521123.hatenablog.com/entry/2024/04/17/132415
egg / wheel ファイルを作成する
https://dk521123.hatenablog.com/entry/2020/02/09/234350
パッケージ管理 ~ pip ~
https://dk521123.hatenablog.com/entry/2021/07/02/000000
オフライン環境下で pip install するには
https://dk521123.hatenablog.com/entry/2021/07/10/164833
TOML
https://dk521123.hatenablog.com/entry/2023/04/25/103533