Skip to content

Commit 2a71cb9

Browse files
committed
Expand pyproject.toml guide to also cover the [build-system] table
1 parent a918470 commit 2a71cb9

File tree

1 file changed

+87
-16
lines changed

1 file changed

+87
-16
lines changed

source/guides/writing-pyproject-toml.rst

Lines changed: 87 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,98 @@
44
Writing your ``pyproject.toml``
55
===============================
66

7-
``pyproject.toml`` is a configuration file used by packaging tools. Most
8-
:term:`build backends <build backend>` [#poetry-special]_ allow you to specify
9-
your project's basic metadata, such as the dependencies, your name, etc.,
10-
in the ``[project]`` table of your ``pyproject.toml``.
7+
``pyproject.toml`` is a configuration file used by packaging tools, as
8+
well as other tools such as linters, type checkers, etc. There are
9+
three possible TOML tables in this file.
10+
11+
- The ``[build-system]`` table is **strongly recommended**. It allows
12+
you to declare which :term:`build backend` you use and which other
13+
dependencies are needed to build your project.
14+
15+
- The ``[project]`` table is the format that most build backends use to specify
16+
your project's basic metadata, such as the dependencies, your name, etc.
17+
18+
- The ``[tool]`` table has arbitrary subtables corresponding to tools, whether
19+
packaging-related or not, e.g., ``[tool.hatch]``, ``[tool.black]``,
20+
``[tool.mypy]``. We only touch upon this table here because its contents are
21+
entirely tool-specific. Consult each tool's documentation to know what it can
22+
contain.
1123

1224
.. note::
1325

14-
You may have heard of ``setup.py`` and ``setup.cfg`` for the setuptools_
15-
build backend. For new projects, it is recommended to use ``pyproject.toml``
16-
for basic metadata, and keep ``setup.py`` only if some programmatic configuration
17-
is needed (especially building C extensions). However, putting basic project
18-
metadata in ``setup.py`` or ``setup.cfg`` is still valid. See
26+
There is a significant difference between the ``[build-system]`` and
27+
``[project]`` tables. The former should always be present, regardless of
28+
which build backend you use (since it *defines* the tool you use). The latter
29+
is understood by *most* build backends, but some build backends use a
30+
different format.
31+
32+
At the time of this writing (November 2023), Poetry_ is a notable build
33+
backend that does not use the ``[project]`` table (it uses the
34+
``[tool.poetry]`` table instead).
35+
36+
Also, the setuptools_ build backend supports both the ``[project]`` table,
37+
and the older format in ``setup.cfg`` or ``setup.py``. For new projects, it
38+
is recommended to use the ``[project]`` table, and keep ``setup.py`` only if
39+
some programmatic configuration is needed (especially building C extensions),
40+
but the ``setup.cfg`` and ``setup.py`` formats are still valid. See
1941
:ref:`setup-py-deprecated`.
2042

2143

44+
45+
Declaring the build backend
46+
===========================
47+
48+
The ``[build-system]`` table contains a ``build-backend`` key, which specifies
49+
the build backend to be used. It also contains a ``requires`` key, which is a
50+
list of dependencies needed to build the project -- this is typically just the
51+
build backend package, but it may also contain additional dependencies. You can
52+
also constrain the versions, e.g., ``requires = ["setuptools >= 61.0"]``.
53+
54+
Usually, you'll just copy what your build backend's documentation suggests. Here
55+
are the values for some common build backends:
56+
57+
.. tab:: Hatchling
58+
59+
.. code-block:: toml
60+
61+
[build-system]
62+
requires = ["hatchling"]
63+
build-backend = "hatchling.build"
64+
65+
.. tab:: setuptools
66+
67+
.. code-block:: toml
68+
69+
[build-system]
70+
requires = ["setuptools>=61.0"]
71+
build-backend = "setuptools.build_meta"
72+
73+
.. tab:: Flit
74+
75+
.. code-block:: toml
76+
77+
[build-system]
78+
requires = ["flit_core>=3.4"]
79+
build-backend = "flit_core.buildapi"
80+
81+
.. tab:: PDM
82+
83+
.. code-block:: toml
84+
85+
[build-system]
86+
requires = ["pdm-backend"]
87+
build-backend = "pdm.backend"
88+
89+
90+
The rest of this guide is devoted to the ``[project]`` table.
91+
92+
2293
Static vs. dynamic metadata
2394
===========================
2495

25-
Most of the time, you will directly write the value of a field in
26-
``pyproject.toml``. For example: ``requires-python = ">= 3.8"``, or
27-
``version = "1.0"``.
96+
Most of the time, you will directly write the value of a ``[project]``
97+
field. For example: ``requires-python = ">= 3.8"``, or ``version =
98+
"1.0"``.
2899

29100
However, in some cases, it is useful to let your build backend compute
30101
the metadata for you. For example: many build backends can read the
@@ -316,6 +387,10 @@ A full example
316387

317388
.. code-block:: toml
318389
390+
[build-system]
391+
requires = ["hatchling"]
392+
build-backend = "hatchling.build"
393+
319394
[project]
320395
name = "spam-eggs"
321396
version = "2020.0.0"
@@ -370,10 +445,6 @@ A full example
370445
371446
------------------
372447

373-
.. [#poetry-special] At the time of this writing (November 2023), Poetry_
374-
is a notable exception. It uses its own format for this metadata, in
375-
the ``[tool.poetry]`` table.
376-
377448
.. [#requires-python-upper-bounds] Think twice before applying an upper bound
378449
like ``requires-python = "<= 3.10"`` here. `This blog post <requires-python-blog-post_>`_
379450
contains some information regarding possible problems.

0 commit comments

Comments
 (0)