PEP 643: Further updates (#1713)

This commit is contained in:
Paul Moore 2020-11-14 20:43:39 +00:00 committed by GitHub
parent acb6e4c0a0
commit aaeeaeaefb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 75 additions and 67 deletions

View File

@ -7,7 +7,7 @@ Status: Draft
Type: Standards Track Type: Standards Track
Content-Type: text/x-rst Content-Type: text/x-rst
Created: 24-Oct-2020 Created: 24-Oct-2020
Post-History: 24-Oct-2020, 01-Nov-2020, 02-Nov-2020 Post-History: 24-Oct-2020, 01-Nov-2020, 02-Nov-2020, 14-Nov-2020
Abstract Abstract
@ -17,7 +17,7 @@ Python package metadata is stored in the distribution file in a standard
format, defined in the `Core Metadata Specification`_. However, for format, defined in the `Core Metadata Specification`_. However, for
source distributions, while the format of the data is defined, there has source distributions, while the format of the data is defined, there has
traditionally been a lot of inconsistency in what data is recorded in traditionally been a lot of inconsistency in what data is recorded in
the sdist. See `here the source distribution. See `here
<https://discuss.python.org/t/why-isnt-source-distribution-metadata-trustworthy-can-we-make-it-so/2620>`_ <https://discuss.python.org/t/why-isnt-source-distribution-metadata-trustworthy-can-we-make-it-so/2620>`_
for a discussion of this issue. for a discussion of this issue.
@ -28,9 +28,7 @@ mechanisms to extract medatata.
This PEP defines a standard that allows build backends to reliably store This PEP defines a standard that allows build backends to reliably store
package metadata in the source distribution, while still retaining the package metadata in the source distribution, while still retaining the
necessary flexibility to handle metadata fields that have to be calculated necessary flexibility to handle metadata fields that have to be calculated
at build time. It further defines a set of metadata values that must be at build time.
fixed when the sdist is created, ensuring that consumers have a minimum
"core" of metadata they can be sure is available.
Motivation Motivation
@ -51,84 +49,87 @@ stored in source distributions:
This PEP proposes an update to the metadata specification to allow This PEP proposes an update to the metadata specification to allow
recording of fields which are expected to be "filled in later", and recording of fields which are expected to be "filled in later", and
updates the sdist specification to clarify that backends should record updates the source distribution specification to clarify that backends
sdist metadata using that version of the spec (or later). It restricts should record sdist metadata using that version of the spec (or later).
which fields can be "filled in later", so that a core set of metadata is
available, and reliable, when read from a sdist.
Rationale Rationale
========= =========
:pep:`621` proposes a mechanism for users to specify metadata in This PEP allows projects to define source distribution metadata values
``pyproject.toml``. As part of that mechanism, a way was needed to say as being "dynamic". In this context, saying that a field is "dynamic"
that a particular field is defined dynamically by the backend. During means that the value has not been fixed at the time that the source
discussions on the PEP, it became clear that the same type of mechanism distribution was generated. Dynamic values will be supplied by the build
would address the issue of distinguishing between "not known yet" and backend at the time when the wheel is generated, and could depend on
"definitely has no value" in sdists. This PEP defines the ``Dynamic`` details of the build environment.
metadata field by analogy with the ``dynamic`` field in :pep:`621`.
:pep:`621` has a similar concept, of "dynamic" values that will be
"filled in later", and so we choose to use the same term here by
analogy.
Specification Specification
============= =============
This PEP defines the relationship between metadata values specified in This PEP defines the relationship between metadata values specified in a
a sdist, and the corresponding values in wheels built from that sdist. source distribution, and the corresponding values in wheels built from
It requires build backends to clearly mark any fields which will *not* it. It requires build backends to clearly mark any fields which will
simply be copied unchanged from the sdist to the wheel. *not* simply be copied unchanged from the sdist to the wheel.
In addition, this PEP makes the `PyPA Specifications`_ document the In addition, this PEP makes the `PyPA Specifications`_ document the
canonical location for the specification of the sdist format (collecting canonical location for the specification of the source distribution
the information in :pep:`517` and in this PEP). format (collecting the information in :pep:`517` and in this PEP).
A new field, ``Dynamic``, will be added to the `Core Metadata Specification`_. A new field, ``Dynamic``, will be added to the `Core Metadata Specification`_.
This field will be multiple use, and will be allowed to contain the name This field will be multiple use, and will be allowed to contain the name
of another core metadata field. The ``Dynamic`` metadata item is only of another core metadata field.
allowed in source distribution metadata.
If tools that read metadata encounter the ``Dynamic`` field anywhere except When found in the metadata of a source distribution, the following
in a sdist, they MAY fail with an error. If they do not fail, they MUST rules apply:
ignore the field, and may report a warning.
If a field is marked as ``Dynamic``, there is no restriction placed on 1. If a field is *not* marked as ``Dynamic``, then the value of the field
its value in a wheel built from the sdist. A field which is marked as in any wheel built from the sdist MUST match the value in the sdist.
``Dynamic``, MUST NOT have an explicit value in the sdist. If the field is not in the sdist, and not marked as ``Dynamic``, then
it MUST NOT be present in the wheel.
2. If a field is marked as ``Dynamic``, it may contain any valid value in
a wheel built from the sdist (including not being present at all).
3. Backends MUST NOT mark a field as ``Dynamic`` if they can determine that
it was generated from data that will not change at build time.
If a field is *not* marked as ``Dynamic``, then the value of the field Backends MAY record the value they calculated for a field they mark as
in any wheel built from the sdist MUST match the value in the sdist. ``Dynamic`` in a source distribution. Consumers, however, MUST NOT treat
If the field is not in the sdist, and not marked as ``Dynamic``, then it this value as canonical, but MAY use it as an hint about what the final
MUST NOT be present in the wheel. value in a wheel could be.
Build backends MUST ensure that these rules are followed, and MUST In any context other than a source distribution, if a field is marked as
report an error if they are unable to do so. ``Dynamic``, that indicates that the value was generated at wheel build
time and may not match the value in the sdist (or in other builds of the
project). Backends are not required to record this information, though,
and consumers MUST NOT assume that the lack of a ``Dynamic`` marking has
any significance, except in a source distribution.
The following fields are the only ones allowed to be marked as ``Dynamic``: The fields ``Name`` and ``Version`` MUST NOT be marked as ``Dynamic``.
* ``Platform``
* ``Supported-Platform``
* ``Requires-Dist``
* ``Requires-External``
* ``Provides-Extra``
* ``Provides-Dist``
* ``Obsoletes-Dist``
As it adds a new metadata field, this PEP updates the core metadata As it adds a new metadata field, this PEP updates the core metadata
format to version 2.2. format to version 2.2.
Source distributions MUST use the latest version of the core metadata Source distributions SHOULD use the latest version of the core metadata
specification (which will be version 2.2 or later). specification that was available when they were created.
Build backends SHOULD encourage projects to avoid using ``Dynamic``, Build backends are strongly encouraged to only mark fields as
preferring to use environment markers on static values to adapt to ``Dynamic`` when absolutely necessary, and to encourage projects to
avoid backend features that require the use of ``Dynamic``. Projects
should prefer to use environment markers on static values to adapt to
details of the install location. details of the install location.
Backwards Compatibility Backwards Compatibility
======================= =======================
As this proposal increments the core metadata version, it is compatible As this proposal increments the core metadata version, it is compatible
with existing sdists, which will use an older metadata version. Tools with existing source distributions, which will use an older metadata
can determine whether a sdist conforms to this PEP by checking the version. Tools can determine whether a source distribution conforms to
metadata version. this PEP by checking the metadata version.
Security Implications Security Implications
@ -159,6 +160,10 @@ Rejected Ideas
so the PEP chooses to make dynamic fields the exception, and require so the PEP chooses to make dynamic fields the exception, and require
backends to "opt in" to making a field dynamic. backends to "opt in" to making a field dynamic.
In addition, if dynamic is the default, then in future, as more
and more metadata becomes static, metadata files will include an
increasing number of ``Static`` declarations.
2. Rather than having a ``Dynamic`` field, add a special value that 2. Rather than having a ``Dynamic`` field, add a special value that
indicates that a field is "not yet defined". indicates that a field is "not yet defined".
@ -169,26 +174,29 @@ Rejected Ideas
does not seem to be enough benefit to this approach to make it worth does not seem to be enough benefit to this approach to make it worth
using instead of the proposed mechanism. using instead of the proposed mechanism.
3. Allow ``Requires-Python`` to be ``Dynamic``, as it cannot include environment 3. Allow ``Requires-Python`` to be ``Dynamic``, as it cannot include
markers to tailor the requirement to the target environment. environment markers to tailor the requirement to the target
environment.
Currently, no projects on PyPI have a ``Requires-Python`` value that varies Currently, no projects on PyPI have a ``Requires-Python`` value that
between different wheels for the same version, so there is no practical varies between different wheels for the same version, so there is no
need for this flexibility at present. If a genuine use case is identified practical need for this flexibility at present. If a genuine use case
later, the specification can be changed to allow ``Rquires-Python`` to be is identified later, the specification can be changed to allow
dynamic at that time. ``Requires-Python`` to be dynamic at that time.
4. Allow ``Dynamic`` to be used in wheels and/or installed distributions. In fact, this became irrelevant during subsequent discussions, when
the explicit whitelist of fields allowed to be ``Dynamic`` was
removed.
There is no obvious value to allowing this, and it seems like it is simply 4. Restrict the use of ``Dynamic`` to a minimal "white list" of
adding complexity for no real reason. Allowing this could be done in a permitted fields.
follow-up proposal if there turned out to be sufficient benefit.
5. Allow a field to be marked as ``Dynamic``, but *also* have a value in the This approach was likely to prove extremely difficult for setuptools
sdist metadata. to implement in a backward compatible way, due to the dynamic nature
of the setuptools interface. Instead, the proposal now allows most
fields to be dynamic, but encourages backends to avoid dynamic values
unless essential.
There appears to be no use case for allowing this. If a use case is
identified in the future, the specification can be updated at that time.
Open Issues Open Issues
=========== ===========