pyproject.toml の仕様

警告

これは 技術的な正式の仕様 です。 pyproject.toml の配慮があってユーザに優しいガイド文書としては、 pyproject.toml を書く を見てください。

pyproject.toml ファイルは、(他のツール類と同様に) パッケージング関係のツール類向けの設定ファイルとして働きます。

pyproject.toml ファイルは TOML で書かれています。現在は、 [build-system] ・ [project] ・ [tool] の3個のテーブルが制定されています。他のテーブル群は将来の使用 (ツールに特有の設定は [tool] テーブルを使うべきです) に備えて予約されています。

ビルドシステムの依存関係を宣言する: [build-system] テーブル

[build-system] テーブルでは、プロジェクトのビルドシステムが成功裡に動作するためにインストールされていなくてはならない Python レベルの依存関係をすべて宣言します。

[build-system] テーブルは、ビルドに関連したデータを格納するために使われます。当初は、テーブル内に requires というたったひとつのキーだけが正当、かつ、必須とされました。このキーは、ビルドシステムを実行するのに要求される依存関係を表現する文字列のリストを値に取らなければなりません。このリストの中の文字列は、 バージョン指定子仕様 に従います。

setuptools と共にビルドされるプロジェクトにおける [build-system] の例は:

[build-system]
# Minimum requirements for the build system to execute.
requires = ["setuptools"]

ビルドツール群は、 pyproject.toml ファイルが存在しない場合には、上に例示された設定ファイルをデフォルトのセマンティクスとして使用することを期待されています。

ツール類は、 [build-system] テーブルの存在を (必須のものとして) 要求するべきではありません。 pyproject.toml ファイルにはビルドに関係するデータ以外の設定の詳細を格納して使われることがあるので、 [build-system テーブルが存在していなくても正当なものであると言えます。ファイルは存在するが [build-system] テーブルが欠けている場合、上記のデフォルトの値を使用するべきです。テーブルは存在しているけれども必須のフィールドが欠けている場合には、ツールはこれをエラーであると判断するべきです。

もし、ファイルが存在していて、 [build-system] テーブルが欠落しており、かつ、そのプロジェクトがビルドされるべきであるかに関する明白な指示がない (例えば、 setup.py/setup.cfg またはその他のビルド設定ファイルが欠落しており、かつ、 [project] テーブルが欠落している) のであれば、ツール類は、ユーザに対してエラーを提示することを選択しても構いません。

TOMLファイルからのデータで実例を示す目的だけに使われるようなタイプ特有の表現を提供するためには、後述の JSON スキーマ がデータフォーマットとして適しているでしょう:

{
    "$schema": "http://json-schema.org/schema#",

    "type": "object",
    "additionalProperties": false,

    "properties": {
        "build-system": {
            "type": "object",
            "additionalProperties": false,

            "properties": {
                "requires": {
                    "type": "array",
                    "items": {
                        "type": "string"
                    }
                }
            },
            "required": ["requires"]
        },

        "tool": {
            "type": "object"
        }
    }
}

プロジェクトのメタデータを宣言する: [project] テーブル

[project] テーブルは、プロジェクトの コアとなるメタデータ を定義します。

メタデータにはふたつの種類があります: 静的 なものと 動的 なものです。静的なメタデータは pyproject.toml ファイルで直接指定されていて、ツール側では指定したり変更したりできません (これは、例えばメタデータが参照するファイルの内容のような、メタデータによって 参照 されるデータを含みます)。動的なメタデータは dynamic キー (この仕様内で後で定義します) を経由して一覧化されていて、ツール側が後から提供することになるでしょう。

その値が任意のエントリのリストないしテーブルであるようなキーは、静的に指定してもよく、 かつ 同時に dynamic 内に列挙されても構いません。そのような場合には、静的に与えられたエントリは固定されていて、ビルド用バックエンドはそれらに対してさらにエントリを 追加 しても良いだけで; バックエンドは、静的に指定されたエントリのひとつとして削除・順序変更・修正を行ってはいけません。詳細については、 dynamic キーを参照して下さい。

[project] テーブルが欠損している場合は、暗黙理に、 ビルドバックエンド が動的にすべてのキーを準備することを意味します。

必ず静的に定義しなければならない必須のキーは次の通り:

  • 名称

必須フィールドだが、静的に指定しても動的に指定しても いずれでも構わない キーは以下の通り:

  • version

他の全てのキーは必須ではないものと解釈され、これらは静的に指定しても動的にリストしても未指定のままにしていても構いません。

[project] テーブルで許容されるキーの完全なリストは次のとおりです:

  • 著者 <authors>

  • 分類詞 <classifiers>

  • 依存関係 <dependencies

  • 説明 <description>

  • dynamic

  • entry-points

  • gui スクリプト <gui-scripts>

  • import-names

  • import-namespaces

  • keywords

  • ライセンス

  • license-files

  • 保守者 <maintainers>

  • 名称

  • optional-dependencies

  • readme

  • requires-python

  • scripts

  • urls

  • version

名称

プロジェクトの名前。

内部的な一貫性を保つために、ツール側では読み取ったらすぐに、この名前を 正規化 するべきです。

version

バージョン指定子仕様 で定義されるものとしての、プロジェクトのバージョン。

ユーザは正規化済みのバージョンを指定するようにするべきです。

説明 <description>

1行で書かれたプロジェクトに関する説明の要約。これが複数行に渡る場合には、ツールはエラーを発生させても構いません。

readme

プロジェクトの説明全体 (すなわち README)。

このキーは文字列かテーブルを受け付けます。もし文字列なら、完全な説明を含むテキストファイルの位置を pyproject.toml からの相対パスで示したものです。ツールの側ではこのファイルが UTF-8 でエンコードされているものと想定しなければなりません。ファイルパスが大文字小文字を問わず .md 拡張子で終わっている場合は、ツールはそのファイルの content-type が text/markdown であるものと仮定しなければなりません。ファイルパスが大文字小文字を問わず .rst で終わっている場合は、ツールは content-type が text/x-rst であるものと仮定しなければなりません。この仕様で指定するよりも多くの拡張子をツールが認識するなら、そのようなツールは、このキーを dynamic であると指定していなくても、ユーザのために content-type を推測しても構いません。content-type が与えられていない場合には、全ての認識できない拡張子についてツールはエラーを発生させなければなりません。

readme キーはその値がテーブルでも構いません。 file キーは、完全な説明を含むファイルへの pyproject.toml ファイルからの相対パスを表現する文字列を値として持ちます。 text キーは、完全な説明そのものである文字列を値に持ちます。これらのキーは排他的にいずれかひとつしか使えないので、もしメタデータがこれら両方のキーを同時に指定していたらツールはエラーを発生させなければなりません。

readme キーに指定されたテーブルには、完全な説明の content-type を指定する文字列を値とする content-type キーも含まれています。メタデータがこのキーをテーブルの中で指定していない場合には、ツールはエラーを発生させなければなりません。メタデータで charset パラメータが指定されていない場合には、 UTF-8 であるものと想定されます。ツールは各ツールが独自に選択した他のエンコーディングをサポートしても構いません。 コアとなるメタデータ によってサポートされている content-type に変換することができるのであれば、ツールはそのような代替 content-type をサポートしても構いません。そうでなければ、ツールはサポートしていない content-type に対してエラーを発生させなければなりません。

requires-python

プロジェクトが要求する Python のバージョン。

ライセンス

ライセンス表現 の中で指定されている通りの、正当な SPDX ライセンス表現 であるテキスト文字列。ツール類は、表現文字列の正当性検証と大文字小文字正規化を行うべきです。

このキーは、そのライセンス表現が、 pyproject.toml を使ってビルドバックエンドによって生成されたすべての配布物のどれについてでも、指定されたものと同一である場合に のみ 指定されるべきです。ライセンス表現が異なるのであれば、動的なものとして指定するか、または、全く設定しないか、であるべきです。

伝統的仕様

テーブルには二つのキーのうちのいずれか一つを書くことができます。 file キーは、 pyproject.toml からプロジェクトのライセンス情報を含むファイルへの相対パスを値とする文字列を値に持ちます。ツールの側では、そのファイルのエンコーディングが UTF-8 であるものと仮定しなければなりません。 text キーは、プロジェクトのライセンス条項の文字列を値に取ります。これらのキーは相互に排他的で、従って、両方のキーが指定されているメタデータについてツールの側ではエラーを発生させなければなりません。

テーブルサブキー群では、値としての文字列が PEP 639 によって非推奨にされました。

license-files

パッケージと一緒に配布されるライセンスやその他の法律上の通知を含むファイル(群)への、プロジェクトのソースコードツリーの中のパスを、プロジェクトのルートディレクトリ (すなわち、 pyproject.toml 、または、例えば setup.py や setup.cfg その他のような伝統的なプロジェクト設定ファイル群のあるディレクトリ) からの相対パスで指定した配列。

文字列は、 glob のパターン の仕様に倣って、正当な glob パターンを含んでいなければなりません。

パターンは、 pyproject.toml を含むディレクトリからの相対パスで、

ツール類は、ライセンスファイルの内容が正当な UTF-8 エンコードのテキストであると想定しなければならず、また、これを検証して、もし正当でなければエラーを発生させなければなりません。

ビルドツール:

  • すべての配布物アーカイブ中の、列挙されたパターンにバッチするすべてのファイルを含めなければなりません。

  • コアとなるメタデータの中の License-File フィールドの下にあるファイルパスで合致したもののそれぞれを列挙しなければなりません。

license-files キーが存在して、かつ、空の配列を値に取っている場合は、ツール類は、ライセンスファイルを一つも含めてはならず、また、エラーを発生させてもいけません。 license-files キーが定義されていなければ、ツール類は、ライセンスファイルをどのように取り扱うかを決定することができます。例えば、ファイルをひとつも含めないことを選択することもできますし、あるいは、独自の論理を用いて配布物中の適切なファイルを発見することもできます。

authors/maintainers

プロジェクトの "作者" であると考えられる人々ないし組織。正確な意味はさまざまに解釈可能です — 元々のまたは主要な作者でも構わないし、現在の保守者やパッケージのオーナでも構いません。

"maintainers" キーは "authors" キーに似ていて、その正確な意味はさまざまに解釈可能です。

これらのキーは、 name と email のふたつのキーを伴ったテーブルの配列を受け入れます。両方の値は文字列でなければなりません。 name の値は、電子メールアドレスにおける正当な名前 (すなわち、 RFC 822 における電子メールアドレスのアドレス部分に前置できる名前なら何でも可) で、コンマを含まないものでなければなりません。 email の値は、正当な電子メールアドレスでなければなりません。これらのキーは共に必須ではありませんが、少なくともいずれかのキーがテーブル内で指定されていなければなりません。

データを使って コアとなるメタデータ に書き込むやり方は次の通りです:

  1. name だけが与えられた場合には、その値を Author なり Maintainer なりに書き込みます。

  2. email だけの場合には、その値を Author-email なり Maintainer-email なりに書き込みます。

  3. email と name の両方が与えられた場合には、 {name} <{email}> のフォーマットで Author-email なり Maintainer-email なりに書き込みます。

  4. 複数の値がある場合はコンマで区切るべきです。

keywords

プロジェクトに関するキーワード。

分類詞 <classifiers>

プロジェクトに適合する Trove 分類子。

License:: 分類子の使用は非推奨になっており、ツール類は、ユーザに対してその由を通知する警告を発行してもかまいません。 (License-Expression メタデータフィールドに翻訳されるところの) license 文字列値と、 License:: 分類子の両方が使われている場合には、ビルドツール類は、エラーを発生させても構いません。

urls

キーが URL ラベルで、値が URL そのものであるような URL のテーブル。表示のためにメタデータを処理する時の標準化のルールとよく知られた <well-known> ルールについては、 メタデータ内のよく知られたプロジェクト URL を見てください。

エントリポイント

みっつのテーブルがエントリポイントに関係しています。 [project.scripts] テーブルは、 エントリポイント仕様 の中の console_scripts グループに対応しています。テーブル内のキーはエントリポイントの名前であり、値は参照されるオブジェクトです。

[project.gui-scripts] テーブルは、 エントリポイント仕様 の中の gui_scripts グループに対応します。そのフォーマットは [project.scripts] と同じです。

[project.entry-points] テーブルは、テーブルの集合体です。それぞれのサブテーブルの名前は、ひとつのエントリポイントグループです。キーと値の意味するところは [project.scripts] と同じです。ユーザはネストしたサブテーブルを作ってはならず、代わりにエントリポイントグループを1段階の深さに保つようにしなければなりません。

メタデータの中に [project.entry-points.console_scripts] もしくは [project.entry-points.gui_scripts] というテーブルが定義されている場合は、それぞれ [project.scripts] や [project.gui-scripts] と混同してしまうといけないので、ビルド時のバックエンドがエラーを発生させなければなりません。

依存関係 <dependencies

dependencies は、そのプロジェクトの期待される依存関係を文字列の配列として列挙します。

それぞれの文字列は、プロジェクトの依存関係を表現していて、正当な 依存関係指定子 として整形されていなければなりません。

それぞれの文字列は、 Requires-Dist エントリに直接に対応付けします。

この配列の中に列挙された依存関係は、常にインストール向けに考慮されていますが、それでも一部の環境ではスキップさせる原因となるような環境マーカを含んでいるかもしれません。

optional-dependencies

optional-dependencies は、各キーが extra を指定していて、その値が dependencies 配列と同じフォーマットを用いた文字列の配列であるテーブルです (配列内の文字列は、正当な 依存関係指定子 でなければなりません) 。

キーは、 Provides-Extra の正当な値でなければなりません。配列の中のそれぞれの値は、したがって、一致する Provides-Extra メタデータに対応する Requires-Dist エントリということになります。

これらの依存関係がオプションであることは、関連する Requires-Dist エントリで extra 名称を確認することで環境マーカ節を修正することで記録されます。オプションの依存関係は、したがって、インストール時に関係する extra 名称が要求されるか否かによってのみ考慮されます。

Dependency specifiers in an extra may self-reference other extras from the current project (e.g. all = ["your-project-name[gui, cli]"]). See self-referential extras for an example. Most package managers now support this kind of extra, including pip, uv, poetry, hatch, pdm and Pipenv.

import-names

インストール時にプロジェクトが排他的に提供したインポートネームを指定する文字列の配列。各文字列は、正当な Python 識別子か空値でなければなりません。インポートネームは、セミコロンと "private" という用語 (例えば "; private") を、セミコロンの前後に空白文字がいくつあっても良い形で、後続させても構いません。

プロジェクトは、そのプロジェクトが排他的に提供した最短のインポートネームをすべて列挙するべきです。最短のネームがドットで区切られたものなら、そのネームからトップレベルに至るすべての中間ネームもまた、 import-names と import-namespaces のいずれか又は両方に適切に列挙されているべきです。例えば、 spam という名前の単一パッケージで複数のサブモジュールを伴っているあるプロジェクトは、 project.import-names=["spam"] だけを列挙することでしょう。 spam.bacon.eggs を列挙しているプロジェクトなら、 spam と spam.bacon についても import-names と import-namespaces の中で適切に考慮しておく必要があるでしょう。すべてのネームを列挙することは、インポートネームに込められた意図が期待通りであることの確認として作動します。同様に、プロジェクトは、それが public であるか private であるかを ; private 修正子を適切に使用してすべてのインポートネームを列挙するべきです。

プロジェクトが同一のネームを import-names と import-namespaces の両方に列挙している場合、ツール類は、曖昧さの故にエラーを発生させなければなりません。

プロジェクトは、プロジェクトがインポートネームを一つも伴わないこと (つまり、配布物ファイルの中には Python モジュールがひとつも存在しないということ) を表現するために、 import-names を空の配列に設定しても構いません。

project.dynamic の中のそのキーをユーザが宣言しているなら、ビルド用バックエンドは、その値を動的に計算することをサポートしても構いません。

例:

[project]
name = "pillow"
import-names = ["PIL"]
[project]
name = "myproject"
import-names = ["mypackage", "_private_module ; private"]

import-namespaces

インストール時にプロジェクトが非排他的に提供したインポートネームを指定する文字列の配列。各文字列は、正当な Python 識別子でなければなりません。インポートネームは、セミコロンの前後には任意の量の空白文字があっても構わないという形で、セミコロンと "private" という用語をその後ろに伴っても構いません (例えば "; private")。 import-names とは異なって、 import-namespaces は空の配列であってはいけません。

プロジェクトは、そのプロジェクトによって排他的に提供された最短インポートネームをすべて列挙するべきです。最短ネームのいずれかがドットで区切られたネームであれば、そのネームからトップレベルのネームに至る中間のネームは、すべて、 import-names と import-namespaces のいずれかまたは両方に適切に列挙されているべきです。

このフィールドは、複数のプロジェクトが同一のインポート名前空間に貢献することができるような名前空間パッケージのために使用されます。 import-namespaces に同じインポートネームを列挙しているプロジェクト群を、それぞれ互いに隠蔽してしまうことなしに一緒にインストールすることができます。

プロジェクトが同一のネームを import-names と import-namespaces の両方に列挙している場合、ツール類は、曖昧さの故にエラーを発生させなければなりません。

project.dynamic の中のそのキーをユーザが宣言しているなら、ビルド用バックエンドは、その値を動的に計算することをサポートしても構いません。

例:

[project]
name = "zope-interface"
import-namespaces = ["zope"]
import-names = ["zope.interface"]

dynamic

この PEP に列挙されたキーのどれを意図的に指定しないままにすることで他のツールが動的にそのようなメタデータを準備することができる/しようとするかを規定します。後述するツールによる設定に比較して、どのメタデータが目的を持って未指定にされていて未指定のままであることを期待されているのかについて明確に描き出します。

  • ビルド用のバックエンドは、静的に指定されたメタデータ (つまり dynamic 内に列挙されたキーではないメタデータ) を尊重しなければなりません。

  • メタデータで dynamic 内に name が指定されている場合には、ビルド用バックエンドがエラーを発生させなければなりません。

  • コアとなるメタデータ の仕様において、あるキーが "必須である" ものとして挙げられている場合には、メタデータはそのキーを静的に指定するか、または、 dynamic 内に指定するかしなければなりません (どちらでもない場合にはビルドバックエンドがエラーを発生させなければなりません、すなわち、必須のフィールドが [project] テーブルの中にどんな形でも存在していないということは不可能であるべきです)。

  • コアとなるメタデータ の仕様で、あるキーを "必須ではない" ものとして挙げている場合には、後でビルド用バックエンドがそのキー用のデータを提供するという期待が持てるのであればメタデータではそのキーを dynamic の中に挙げても構いません。

  • 以下に列挙するように、そのキーが展開可能な知るとないし任意のテーブルでない限り、メタデータ内のあるキーが静的に指定されていて、かつ、 dynamic にも挙げてある場合には、ビルド用バックエンドはエラーを発生させなければなりません。

  • メタデータ内で、あるキーを dynamic の中に挙げなかった場合は、ビルド用バックエンドがユーザに代わって必要なメタデータを挿入することはできません (すなわち、ツールがメタデータを挿入できるのは dynamic の中だけであり、かつ、ユーザがそうするようにオプトインしていなければならないということです) 。

  • あるキーが dynamic の中で指定されたメタデータで、しかし、ビルド用バックエンドがそこに挿入するべきデータを決定することができない時は、ビルド用バックエンドはエラーを発生させなければなりません (正確な値であると判断した場合はデータを省略することが許容されます) 。

その値が任意のエントリのリストないしテーブルであるようなキーは、静的に指定され、かつ、同時に dynamic に列挙されても構いません。この説明に合致するキーというのは:

  • 著者 <authors>

  • 分類詞 <classifiers>

  • 依存関係 <dependencies

  • entry-points

  • gui スクリプト <gui-scripts>

  • import-names

  • import-namespaces

  • keywords

  • license-files

  • 保守者 <maintainers>

  • optional-dependencies

  • scripts

  • urls

そのようなキーが同時に静的かつ dynamic 内に列挙された時:

  • A build back-end MAY only append entries to the value; it MUST NOT remove, reorder, or modify any statically-specified entries. For tables (such as optional-dependencies or entry-points) this means a back-end MAY add new keys and MAY append to the values of existing keys (in the case of a list), but MUST NOT change or remove the entries given statically.

  • A build back-end SHOULD raise an error if a key is listed in dynamic and it does not support extending that key.

任意のツールの設定: [tool] テーブル

[tool] テーブルは、ビルドツールに限らずその Python プロジェクトに関係するツールであれば何であっても、 [tool] 内のサブテーブルを使う限りはユーザが設定データを指定することができるもので、例えば flit ツールならその設定を [tool.flit] に格納しておくでしょう。

tool.* という名前空間の中に名称を確保するには、他のプロジェクトが同じサブテーブルを使おうと試みて衝突してしまうようなことにならないようにするメカニズムが必要です。我々のルールは、あるプロジェクトが Cheeseshop/PyPI に $NAME というエントリを保有している場合、その場合に限って、 tool.$NAME なるサブテーブルを使うことができるというものです。

歴史

  • 2016年5月: PEP 518 を通じて、 pyproject.toml ファイルの初期の仕様、つまり、 [build-system] が requires キーと [tool] テーブルしか含んでいないものが承認されました。

  • 2020年11月: PEP 621 を通じて、 [project] テーブルの仕様が承認されました。

  • 2024年12月: PEP 639 を通じて、 license キーが再定義され、 license-files キーが追加され、 License:: 分類子が非推奨になりました。

  • 2025年9月: license キーが、 pyproject.toml ファイルから生成されたすべての配布物のファイル群に適用されることが明確化されました。

  • 2025年10月: PEP 794 を通じて import-names キーと import-namespaces キーが追加されました。

  • 2026年1月: PEP 508 への直接参照が旧式になったので、 依存関係指定子 への参照で置き換えました。

  • May 2026: Allowed list and table keys to be specified statically as well as listed in dynamic, with build back-ends only able to append entries, through PEP 808.

  • August 2026: Document self-referential extra as a supported feature by many modern package managers of Python.