Skip to content

Commit 63d3a9c

Browse files
henryiiiwillingc
andauthored
PEP 808: how to teach update (#4711)
Co-authored-by: Carol Willing <carolcode@willingconsulting.com>
1 parent 93f3c30 commit 63d3a9c

File tree

1 file changed

+52
-46
lines changed

1 file changed

+52
-46
lines changed

peps/pep-0808.rst

Lines changed: 52 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ Abstract
1717
========
1818

1919
This PEP relaxes the constraint on dynamic metadata listed in the ``[project]``
20-
section in ``pyproject.toml`` to allow the static portion of mixed metadata to
21-
be defined in the normal location if the field is a table or array by having
22-
the dynamic fields extend the static ones.
20+
section in ``pyproject.toml``. It is now permitted to define a static portion
21+
of a dynamic metadata field in the ``[project]`` table as long as the field is
22+
a table or array.
2323

2424
This allows users to opt into allowing a backend to extend metadata while still
2525
keeping the static portions of the metadata defined in the standard location in
@@ -52,9 +52,9 @@ as creating "used by" and "uses" graphs. It is used for code quality tooling to
5252
detect the minimum supported version of Python. It is used by cibuildwheel_ to
5353
automatically avoid building wheels that are not supported. It is not used,
5454
however, to avoid wheel builds when the SDist is available; that was addressed
55-
by METADATA 2.2, which a ``Dynamic`` field in the SDist metadata that lets a
56-
tool know if the metadata can change when making a wheel - this is an easy
57-
mistake to make due to the similarity of the names.
55+
by METADATA 2.2, which added a ``Dynamic`` field in the SDist metadata that
56+
lets a tool know if the metadata can change when making a wheel - this is an
57+
easy mistake to make due to the similarity of the names.
5858

5959
Due to the rapidly increasing popularity of the project table, support from all
6060
major backends, and a rise of backends supporting complex compiled extensions,
@@ -65,8 +65,8 @@ definition. For the most common use cases, this is fine; there is little
6565
benefit to set the ``version`` statically if you are going to override it
6666
dynamically. If you are using a custom README processor to filter or modify the
6767
README for proper display, it's not a big deal to have to specify the
68-
configuration in a custom ``tool.*`` section. But there is a specific class of
69-
cases where the all-or-nothing approach is problematic: lists of items where
68+
configuration in a custom ``[tool.*]`` section. But there is a specific class
69+
of cases where the all-or-nothing approach is problematic: lists of items where
7070
the backend needs to add items are currently forced to be fully dynamically
7171
specified (that is, in a backend-specific configuration location). This causes
7272
both of the original benefits (standard location and static tooling support) to
@@ -93,8 +93,7 @@ restrictions on the ``[project]`` table and ``project.dynamic`` list.
9393
Every list and every table with arbitrary keys will now be allowed to be
9494
specified both statically, in the ``[project]`` table, and in the
9595
``project.dynamic`` list. If it is present in both places, the build backend
96-
can extend list items and add new keys, but not modify existing list items or
97-
strings.
96+
can extend list items and add new keys, but not modify existing entries.
9897

9998

10099
Use Cases
@@ -107,26 +106,27 @@ cases that have come up:
107106
- Pinning dependency requirements when building the wheel. When building
108107
PyTorch_ extensions, for example, the version you build with adds a constraint
109108
to the wheel you create that is not present with the SDist.
110-
- Generating extra scripts from a build system (this is a currently proposed in
109+
- Generating extra scripts from a build system (this is currently proposed in
111110
scikit-build-core_).
112111
- Adding entry points dynamically (validate-pyproject-schema-store_ could have
113-
used this to generate an entry point for each schema present in the package.)
112+
used this to generate an entry point for each schema present in the package).
114113
- Adding dependencies or optional dependencies based on configuration (such as
115114
making an all dependency, or reading dependencies from dependency-groups, for
116-
example). Adding constraints can also be useful; pybind11_ uses adds a ``global``
115+
example). Adding constraints can also be useful; pybind11_ uses a ``global``
117116
extra that pins ``pybind11-global==<version>``, as both packages are in the
118117
same repository and released in sync. toga_ is a collection of packages that
119-
currently is unable to set any static dependencies due to the same sort of
118+
is currently unable to set any static dependencies due to the same sort of
120119
pinning problem.
121120
- Adding classifiers; some backends can compute classifiers from other places
122121
and inject them (Poetry_ being the best known example).
123122
- Adding license files to the wheel based on what libraries are linked in (this
124-
is an active discussion in followup to :pep:`639`).
125-
- Adding SBom's when building - :pep:`770` had to remove the ``pyproject.toml``
123+
is an active discussion in follow-up to :pep:`639`).
124+
- Adding SBOMs when building - :pep:`770` had to remove the ``pyproject.toml``
126125
field specifically because you *want* the build tool to add these, so the
127-
``[project]`` table setting would be useless, you'd almost never be able to
128-
use it.
129-
- Adding generated modules to ``import-names`` or ``import-namespaces``.
126+
``[project]`` table setting would be useless, you would almost never be able
127+
to use it.
128+
- Adding generated modules to ``import-names`` or ``import-namespaces`` is
129+
another example.
130130

131131
All of these use cases have a similar feature: they are adding something
132132
dynamically to a fixed list (possibly a narrower pin for the dependency case).
@@ -141,7 +141,7 @@ availability of metadata for static tooling.
141141
Example: pinning
142142
----------------
143143

144-
For example, let's say you want to allow an imaginary build backend
144+
For example, say you want to allow an imaginary build backend
145145
(``my-build-backend``) to pin to the supported build of PyTorch_. Before this
146146
PEP, you could do this:
147147

@@ -162,16 +162,16 @@ Which would effectively expand to the following SDist metadata:
162162
Requires-Dist: packaging
163163
Requires-Dist: torch
164164
165-
Which would then could make a wheel with this:
165+
Which could then make a wheel with this:
166166

167167
.. code-block:: text
168168
169169
Requires-Dist: packaging
170170
Requires-Dist: torch
171171
Requires-Dist: torch==2.8.0
172172
173-
Static tooling no longer can tell that ``torch`` and ``packaging`` are runtime
174-
dependencies, and the build backend had to duplicate the dependency table,
173+
Static tooling can no longer tell that ``torch`` and ``packaging`` are runtime
174+
dependencies, and the build backend has to duplicate the dependency table,
175175
making it harder for users to learn and read; the standardized place proposed
176176
by :pep:`621` and adopted by all major build backends is lost.
177177

@@ -198,8 +198,8 @@ Future Updates
198198

199199
Loosening this rule to allow purely additive metadata should address many of
200200
the use cases that have been seen in practice. If further changes are needed,
201-
this can be revisited in a future PEP; this PEP neither recommends or precludes
202-
future updates like this.
201+
this can be revisited in a future PEP; this PEP neither recommends nor
202+
precludes future updates like this.
203203

204204
Terminology
205205
===========
@@ -231,13 +231,13 @@ The fields that are arrays or tables with arbitrary entries are:
231231
be changed or removed.
232232
* ``keywords``: Keywords can be added to the list.
233233
* ``license-files``: Files can be added to the list.
234-
* ``optional-dependencies``: A new extra or new items can be added to a
234+
* ``optional-dependencies``: A new extra or new items can be added to an
235235
existing extra.
236236
* ``urls``: New urls can be added. Existing ones cannot be changed or removed.
237237
* ``import-names``, ``import-namespaces``: New import names or namespaces can
238238
be added. Existing ones cannot be modified or removed.
239239

240-
To add items, users must opt-in by listing the field in ``dynamic``; without
240+
To add items, users must opt in by listing the field in ``dynamic``; without
241241
that, the metadata continues to be entirely static.
242242

243243
A backend SHOULD error if a field is specified and it does not support
@@ -250,7 +250,7 @@ Static analysis tools, when detecting a field is both specified and in the
250250
new entries to be present when the package is built.
251251

252252
The ``Dynamic`` field, as specified in :pep:`643`, is unaffected by this PEP,
253-
and backends can continue to fill it as they chose. However, a backend MUST
253+
and backends can continue to fill it as they choose. However, a backend MUST
254254
ensure that both the SDist and the wheel metadata include the static metadata
255255
portion of the project table.
256256

@@ -263,7 +263,7 @@ to do with dynamic metadata.
263263

264264
The pyproject-metadata_ project, which is used by
265265
several build backends, will need to modify the correctness check to account
266-
for the possible extensions; this is in `a draft PR <pyprojectmetdatapr>`__.
266+
for the possible extensions; this is in `a draft PR <pyprojectmetadatapr>`__.
267267

268268
The dynamic-metadata_ project, which provides a plugin
269269
system that backends can use to share dynamic metadata plugins, was designed to
@@ -276,15 +276,15 @@ Backwards Compatibility
276276
Using metadata from SDists or wheels is unaffected. The METADATA version does
277277
not need to be incremented.
278278

279-
This does not affect any existing ``pyproject.toml``'s, since this was strictly
280-
not allowed before this PEP.
279+
This does not affect any existing ``pyproject.toml`` files, since this was
280+
strictly not allowed before this PEP.
281281

282282
When users adopt this in a ``pyproject.toml``, the backend must support it; an
283-
error will be correctly generated if it doesn't following the previous
283+
error will be correctly generated if it doesn't, following the previous
284284
standard. Frontends were never required to throw an error, though some
285285
frontends may need to be updated to benefit from the partially static metadata.
286286
Some frontends and other tooling may need updating, such as schema
287-
validation, just like other ``pyproject.toml`` PEPs.
287+
validators, just like other ``pyproject.toml`` PEPs.
288288

289289
Static analysis tools may require updating to handle this change. Tools should
290290
check the dynamic table first, like this:
@@ -317,19 +317,26 @@ a static component to existing dynamic metadata support.
317317
How to Teach This
318318
=================
319319

320+
If you currently have dynamic metadata, but some list or table entries are
321+
known statically, you can now make that explicit by adding the static entry in
322+
the ``[project]`` table, while also keeping the entry in the
323+
``project.dynamic`` list to allow the dynamic portion to be added by your build
324+
backend.
325+
320326
The current guides that state metadata must not be listed in both ``[project]``
321-
and ``project.dynamic`` can be updated to say that some fields can be extended
322-
by ``project.dynamic``. Since dynamic metadata is already an advanced concept,
323-
this will likely not affect most existing tutorial material aimed at
324-
introductory packaging.
327+
and ``project.dynamic`` can be updated to say that lists and tables marked with
328+
``project.dynamic`` can still have static entries. Since dynamic metadata is
329+
already an advanced concept, this will likely not affect most existing tutorial
330+
material aimed at introductory packaging.
325331

326332
The ``pyproject.toml`` `specification <pyprojectspec>`__ will be updated to
327333
include the behavior of fields when specified and also listed in the dynamic
328334
field.
329335

330-
It should also be noted that specifying something in dynamic will require any
331-
tool that requires the full metadata to invoke the backend even if it is
332-
partially statically specified, so it should not be used unless necessary.
336+
It should also be noted that specifying something in ``dynamic`` will require
337+
any tool that needs the full metadata to invoke the backend even if it is
338+
partially statically specified. So, it should not be used unless necessary,
339+
just like any other dynamic metadata.
333340

334341

335342
Rejected Ideas
@@ -378,12 +385,11 @@ Allow simplifications
378385
An earlier draft of this PEP had a clause allowing backends to simplify some
379386
types of fields; most notably dependency specifiers would have allowed
380387
"tightening", such as ``torch`` being replaced by ``torch>=1.2``, for example.
381-
. This was removed due to it being impossible to ensure a variation will
382-
resolve identically on all resolvers within the current specification, and to
383-
simplify the contract with backends. Any other simplifications would be purely
384-
cosmetic, and so were left out. The order in the current PEP is now required to
385-
match the original static metadata, with the dynamic portion only allowing
386-
insertions.
388+
This was removed due to it being impossible to ensure a variation will resolve
389+
identically on all resolvers within the current specification, and to simplify
390+
the contract with backends. Any other simplifications would be purely cosmetic,
391+
and so were left out. The order in the current PEP is now required to match the
392+
original static metadata, with the dynamic portion only allowing insertions.
387393

388394

389395
Add a general mechanism to specify dynamic-metadata

0 commit comments

Comments
 (0)