@@ -17,9 +17,9 @@ Abstract
1717========
1818
1919This 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
2424This allows users to opt into allowing a backend to extend metadata while still
2525keeping 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
5252detect the minimum supported version of Python. It is used by cibuildwheel _ to
5353automatically avoid building wheels that are not supported. It is not used,
5454however, 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
5959Due to the rapidly increasing popularity of the project table, support from all
6060major 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
6565benefit to set the ``version `` statically if you are going to override it
6666dynamically. If you are using a custom README processor to filter or modify the
6767README 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
7070the backend needs to add items are currently forced to be fully dynamically
7171specified (that is, in a backend-specific configuration location). This causes
7272both of the original benefits (standard location and static tooling support) to
@@ -93,8 +93,7 @@ restrictions on the ``[project]`` table and ``project.dynamic`` list.
9393Every list and every table with arbitrary keys will now be allowed to be
9494specified 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
10099Use 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
131131All of these use cases have a similar feature: they are adding something
132132dynamically to a fixed list (possibly a narrower pin for the dependency case).
@@ -141,7 +141,7 @@ availability of metadata for static tooling.
141141Example: 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
146146PEP, 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,
175175making it harder for users to learn and read; the standardized place proposed
176176by :pep: `621 ` and adopted by all major build backends is lost.
177177
@@ -198,8 +198,8 @@ Future Updates
198198
199199Loosening this rule to allow purely additive metadata should address many of
200200the 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
204204Terminology
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
241241that, the metadata continues to be entirely static.
242242
243243A 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
250250new entries to be present when the package is built.
251251
252252The ``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
254254ensure that both the SDist and the wheel metadata include the static metadata
255255portion of the project table.
256256
@@ -263,7 +263,7 @@ to do with dynamic metadata.
263263
264264The pyproject-metadata _ project, which is used by
265265several 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
268268The dynamic-metadata _ project, which provides a plugin
269269system that backends can use to share dynamic metadata plugins, was designed to
@@ -276,15 +276,15 @@ Backwards Compatibility
276276Using metadata from SDists or wheels is unaffected. The METADATA version does
277277not 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
282282When 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
284284standard. Frontends were never required to throw an error, though some
285285frontends may need to be updated to benefit from the partially static metadata.
286286Some 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
289289Static analysis tools may require updating to handle this change. Tools should
290290check the dynamic table first, like this:
@@ -317,19 +317,26 @@ a static component to existing dynamic metadata support.
317317How 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+
320326The 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
326332The ``pyproject.toml `` `specification <pyprojectspec >`__ will be updated to
327333include the behavior of fields when specified and also listed in the dynamic
328334field.
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
335342Rejected Ideas
@@ -378,12 +385,11 @@ Allow simplifications
378385An earlier draft of this PEP had a clause allowing backends to simplify some
379386types 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
389395Add a general mechanism to specify dynamic-metadata
0 commit comments