Skip to content

Commit 9f860c6

Browse files
committed
Move part part of PEP 517 to the pyproject.toml spec
The description of the data format in pyproject.toml is now part of the pyproject.toml spec, while how the build backend is used remains in the build system interfaces spec.
1 parent 40cbf91 commit 9f860c6

File tree

2 files changed

+125
-127
lines changed

2 files changed

+125
-127
lines changed

source/specifications/build-system-interface.rst

Lines changed: 2 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -24,83 +24,6 @@ combination of wheels and sdists. In a command like ``pip install
2424
lxml==2.4.0``, pip is acting as an integration frontend.
2525

2626

27-
Source trees
28-
============
29-
30-
There is an existing, legacy source tree format involving
31-
``setup.py``. We don't try to specify it further; its de facto
32-
specification is encoded in the source code and documentation of
33-
``distutils``, ``setuptools``, ``pip``, and other tools. We'll refer
34-
to it as the ``setup.py``\-style.
35-
36-
Here we define a new style of source tree based around the
37-
``pyproject.toml`` file defined in :pep:`518`, extending the
38-
``[build-system]`` table in that file with one additional key,
39-
``build-backend``. Here's an example of how it would look::
40-
41-
[build-system]
42-
# Defined by PEP 518:
43-
requires = ["flit"]
44-
# Defined by this PEP:
45-
build-backend = "flit.api:main"
46-
47-
``build-backend`` is a string naming a Python object that will be
48-
used to perform the build (see below for details). This is formatted
49-
following the same ``module:object`` syntax as a ``setuptools`` entry
50-
point. For instance, if the string is ``"flit.api:main"`` as in the
51-
example above, this object would be looked up by executing the
52-
equivalent of::
53-
54-
import flit.api
55-
backend = flit.api.main
56-
57-
It's also legal to leave out the ``:object`` part, e.g. ::
58-
59-
build-backend = "flit.api"
60-
61-
which acts like::
62-
63-
import flit.api
64-
backend = flit.api
65-
66-
Formally, the string should satisfy this grammar::
67-
68-
identifier = (letter | '_') (letter | '_' | digit)*
69-
module_path = identifier ('.' identifier)*
70-
object_path = identifier ('.' identifier)*
71-
entry_point = module_path (':' object_path)?
72-
73-
And we import ``module_path`` and then lookup
74-
``module_path.object_path`` (or just ``module_path`` if
75-
``object_path`` is missing).
76-
77-
When importing the module path, we do *not* look in the directory containing the
78-
source tree, unless that would be on ``sys.path`` anyway (e.g. because it is
79-
specified in PYTHONPATH). Although Python automatically adds the working
80-
directory to ``sys.path`` in some situations, code to resolve the backend should
81-
not be affected by this.
82-
83-
If the ``pyproject.toml`` file is absent, or the ``build-backend``
84-
key is missing, the source tree is not using this specification, and
85-
tools should revert to the legacy behaviour of running ``setup.py`` (either
86-
directly, or by implicitly invoking the ``setuptools.build_meta:__legacy__``
87-
backend).
88-
89-
Where the ``build-backend`` key exists, this takes precedence and the source tree follows the format and
90-
conventions of the specified backend (as such no ``setup.py`` is needed unless the backend requires it).
91-
Projects may still wish to include a ``setup.py`` for compatibility with tools that do not use this spec.
92-
93-
This PEP also defines a ``backend-path`` key for use in ``pyproject.toml``, see
94-
the "In-Tree Build Backends" section below. This key would be used as follows::
95-
96-
[build-system]
97-
# Defined by PEP 518:
98-
requires = ["flit"]
99-
# Defined by this PEP:
100-
build-backend = "local_backend"
101-
backend-path = ["backend"]
102-
103-
10427
Build requirements
10528
==================
10629

@@ -451,6 +374,8 @@ package *authors*, while still allowing *end-users* to open up the
451374
hood and apply duct tape when necessary.
452375

453376

377+
.. _in-tree-build-backends:
378+
454379
In-tree build backends
455380
----------------------
456381

source/specifications/pyproject-toml.rst

Lines changed: 123 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
The ``pyproject.toml`` file acts as a configuration file for packaging-related
1414
tools (as well as other tools).
1515

16-
.. note:: This specification was originally defined in :pep:`518` and :pep:`621`.
16+
.. note:: This specification was originally defined in :pep:`518`,
17+
:pep:`517` and :pep:`621`.
1718

1819
The ``pyproject.toml`` file is written in `TOML <https://toml.io>`_. Three
1920
tables are currently specified, namely
@@ -29,71 +30,100 @@ Declaring build system dependencies: the ``[build-system]`` table
2930

3031
The ``[build-system]`` table declares any Python level dependencies that
3132
must be installed in order to run the project's build system
32-
successfully.
33+
successfully. The valid keys are ``requires``, ``build-backend`` and
34+
``backend-path``.
3335

34-
.. TODO: merge with PEP 517
36+
Tools should not require the existence of the ``[build-system]`` table.
37+
A ``pyproject.toml`` file may be used to store configuration details
38+
other than build-related data and thus lack a ``[build-system]`` table
39+
legitimately.
40+
If the table is specified but is missing required fields then the tool
41+
should consider it an error.
42+
43+
44+
``requires``
45+
------------
46+
47+
The ``requires`` key must have a value of a list of strings representing
48+
dependencies required to execute the build system [#requires-json-schema]_.
49+
The strings in this list follow the :ref:`version specifier specification
50+
<version-specifiers>`.
3551

36-
The ``[build-system]`` table is used to store build-related data.
37-
Initially, only one key of the table is valid and is mandatory
38-
for the table: ``requires``. This key must have a value of a list
39-
of strings representing dependencies required to execute the
40-
build system. The strings in this list follow the :ref:`version specifier
41-
specification <version-specifiers>`.
52+
This key is mandatory if the ``[build-system]`` table is present. If
53+
the ``pyproject.toml`` file is missing, or exists but is lacking the
54+
``[build-system]`` table, then ``requires`` defaults to ``["setuptools"]``.
4255

43-
An example ``[build-system]`` table for a project built with
44-
``setuptools`` is:
56+
57+
58+
``build-backend``
59+
-----------------
60+
61+
The ``build-backend`` key is a string naming a Python object that will be
62+
used to perform the build. This is formatted following the same
63+
``module:object`` syntax as an :ref:`entry point <entry-points>`.
64+
For instance, with the configuration
4565

4666
.. code-block:: toml
4767
4868
[build-system]
49-
# Minimum requirements for the build system to execute.
50-
requires = ["setuptools"]
69+
requires = ["backend-name"]
70+
build-backend = "backend_name.build_system:backend"
5171
52-
Build tools are expected to use the example configuration file above as
53-
their default semantics when a ``pyproject.toml`` file is not present.
72+
this object would be looked up by executing the equivalent of::
5473

55-
Tools should not require the existence of the ``[build-system]`` table.
56-
A ``pyproject.toml`` file may be used to store configuration details
57-
other than build-related data and thus lack a ``[build-system]`` table
58-
legitimately. If the file exists but is lacking the ``[build-system]``
59-
table then the default values as specified above should be used.
60-
If the table is specified but is missing required fields then the tool
61-
should consider it an error.
74+
import backend_name.build
75+
backend = backend_name.build_system.backend
6276

77+
It is also legal to leave out the ``:object`` part, e.g.
6378

64-
To provide a type-specific representation of the resulting data from
65-
the TOML file for illustrative purposes only, the following
66-
`JSON Schema <https://json-schema.org>`_ would match the data format:
79+
.. code-block:: toml
6780
68-
.. code-block:: json
81+
build-backend = "backend_name.build_system"
6982
70-
{
71-
"$schema": "http://json-schema.org/schema#",
83+
which acts like::
7284

73-
"type": "object",
74-
"additionalProperties": false,
85+
import backend_name.build_system
86+
backend = backend_name.build_system
7587

76-
"properties": {
77-
"build-system": {
78-
"type": "object",
79-
"additionalProperties": false,
88+
Formally, the string should satisfy this grammar:
8089

81-
"properties": {
82-
"requires": {
83-
"type": "array",
84-
"items": {
85-
"type": "string"
86-
}
87-
}
88-
},
89-
"required": ["requires"]
90-
},
90+
.. code-block:: text
91+
92+
identifier = (letter | '_') (letter | '_' | digit)*
93+
module_path = identifier ('.' identifier)*
94+
object_path = identifier ('.' identifier)*
95+
entry_point = module_path (':' object_path)?
96+
97+
The module specified by ``module_path`` is imported and the build
98+
backend object is looked up using ``module_path.object_path`` (or
99+
``module_path`` is directly used if ``object_path`` is missing).
100+
See :ref:`build-system-interface` for how the build backend object
101+
is used to perform the build.
102+
103+
When importing the module path, we do *not* look in the directory
104+
containing the source tree, unless that would be on ``sys.path`` anyway
105+
(e.g. because it is specified in PYTHONPATH). Although Python
106+
automatically adds the working directory to ``sys.path`` in some
107+
situations, code to resolve the backend should not be affected by this.
108+
109+
Unlike the ``requires`` key, the ``build-backend`` key is optional
110+
[#build-backend-optional]_. If ``pyproject.toml`` is absent, or
111+
the ``[build-system]`` table is missing, or it does not contain
112+
the ``build-backend`` key, build frontends should revert to the legacy
113+
behavior of running ``setup.py`` (either directly, or implicitly by
114+
invoking the ``setuptools.build_meta:__legacy__`` backend).
115+
116+
117+
``backend-path``
118+
----------------
119+
120+
This key is for use by projects wishing to include their build backend
121+
directly in their source tree, such as build backends themselves. If
122+
provided, it must be a list of directories, which are prepended to
123+
``sys.path`` during the build. For details, see
124+
:ref:`in-tree-build-backends` in the build system interface
125+
specification.
91126

92-
"tool": {
93-
"type": "object"
94-
}
95-
}
96-
}
97127

98128

99129
.. _pyproject-project-table:
@@ -441,8 +471,51 @@ History
441471
=======
442472

443473
This specification was originally defined in :pep:`518` (``[build-system]``
444-
and ``[tool]`` tables) and :pep:`621` (``[project]`` table).
474+
and ``[tool]`` tables), :pep:`517` (``build-backend`` and ``backend-path``
475+
in the ``[build-system]`` table), and :pep:`621` (``[project]`` table).
476+
477+
478+
--------------------------------------------------------------------------
479+
480+
.. [#requires-json-schema] The following `JSON Schema <json-schema_>`_ was
481+
originally provided, for illustrative purposes only, and has not been
482+
updated:
483+
484+
.. code-block:: json
485+
486+
{
487+
"$schema": "http://json-schema.org/schema#",
488+
489+
"type": "object",
490+
"additionalProperties": false,
491+
492+
"properties": {
493+
"build-system": {
494+
"type": "object",
495+
"additionalProperties": false,
496+
497+
"properties": {
498+
"requires": {
499+
"type": "array",
500+
"items": {
501+
"type": "string"
502+
}
503+
}
504+
},
505+
"required": ["requires"]
506+
},
507+
508+
"tool": {
509+
"type": "object"
510+
}
511+
}
512+
}
513+
445514
515+
.. [#build-backend-optional] Historically, ``build-backend`` was defined
516+
later than ``requires``, thus making ``build-backend`` optional is to
517+
preserve backwards compatibility.
446518
447519
448520
.. _TOML: https://toml.io
521+
.. _json-schema: https://json-schema.org

0 commit comments

Comments
 (0)