Skip to content

Commit a17c3e6

Browse files
authored
PEP 751: Updates based on feedback (#4458)
Mostly simplifying and loosening the spec. Also update CODEOWNERS as that was missed when the PEP was initially added.
1 parent 784f1a1 commit a17c3e6

File tree

2 files changed

+72
-62
lines changed

2 files changed

+72
-62
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -666,13 +666,12 @@ peps/pep-0785.rst @gpshead
666666
# ...
667667
peps/pep-0787.rst @ncoghlan
668668
peps/pep-0788.rst @ZeroIntensity @vstinner
669-
# ...
670669
peps/pep-0789.rst @njsmith
671670
peps/pep-0790.rst @hugovk
672671
peps/pep-0791.rst @vstinner
673672
peps/pep-0792.rst @dstufft
674-
# ...
675673
peps/pep-0793.rst @encukou
674+
peps/pep-0794.rst @brettcannon
676675
# ...
677676
peps/pep-0801.rst @warsaw
678677
# ...

peps/pep-0794.rst

Lines changed: 71 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ Abstract
1515

1616
This PEP proposes extending the core metadata specification for Python
1717
packaging to include a new, repeatable field named ``Import-Name`` to record
18-
the import names that a project owns once installed. A new key named
18+
the import names that a project owns/provides once installed. A new key named
1919
``import-names`` will be added to the ``[project]`` table in
20-
``pyproject.toml``. This also leads to the introduction of core metadata
21-
version 2.5.
20+
``pyproject.toml`` for providing the values for the new core metadata field.
21+
This also leads to the introduction of core metadata version 2.5.
2222

2323

2424
Motivation
@@ -32,8 +32,8 @@ the right project to install when they know the import name or knowing what
3232
import names a project will provide once installed.
3333

3434
As an example, a code editor may detect a user has an unsatisfied import in a
35-
selected virtual environment. But with no way to reliably gather the import
36-
names that various projects provide, the code editor cannot accurately
35+
selected virtual environment. But with no way to reliably know what import
36+
names various projects provide, the code editor cannot accurately
3737
provide a user with a list of potential projects to install to satisfy that
3838
import requirement (e.g. it is not obvious that ``import PIL`` very likely
3939
implies the user wants the `Pillow project
@@ -56,21 +56,32 @@ This PEP proposes extending the packaging :ref:`packaging:core-metadata` so
5656
that project owners can specify the highest-level import names that a project
5757
provides and owns if installed.
5858

59-
By keeping the information to the import names a project would own (i.e. not
60-
implicit namespace packages but modules, regular packages, submodules, and
61-
subpackages in an explicit namespace package), it makes it clear which
62-
project maps directly to what import name once the project is installed.
63-
64-
By keeping it to the highest-level name that's owned, it keeps the data small
65-
and allows for inferring implicit namespace packages that a project
66-
contributes to. This will hopefully encourage use when appropriate by not
67-
being a burden to provide appropriate information.
59+
By keeping the information to the import names a project would own if
60+
installed, it makes it clear which project maps directly to what import name
61+
once the project is installed.
6862

6963
Putting this metadata in the core metadata means the data is (potentially)
7064
served independently of any sdist or wheel by an index server. That negates
7165
needing to come up with another way to expose the metadata to tools to avoid
7266
having to download an entire e.g. wheel.
7367

68+
Having this metadata be the same across all release artifacts would allow for
69+
projects to only have to check a single file's core metadata to get all
70+
possible import names instead of checking all the released files. This also
71+
means one does not need to worry if a file is missing when reading the core
72+
metadata or one can work solely from an sdist if the metadata is provided. As
73+
well, it simplifies having a ``project.import-names`` key in
74+
``pyproject.toml`` by having it be consistent for the entire project version
75+
and not unique per released file for the same version.
76+
77+
This PEP is not overly strict on what to (not) list in the proposed metadata on
78+
purpose. Having build back-ends verify that a project is accurately following
79+
a specification that is somehow strict about what can be listed would be near
80+
impossible to get right due to how flexible Python's import system is. As such,
81+
this PEP only requires that valid import names be used and that projects don't
82+
lie (and it is acknowledged the latter requirements cannot be validated
83+
programmatically).
84+
7485
Various other attempts have been made to solve this, but they all have to
7586
make various trade-offs. For instance, one could download every wheel for
7687
every project release and look at what files are provided via the
@@ -79,9 +90,9 @@ bandwidth for something that is static information (although tricks can be
7990
used to lessen the data requests such as using HTTP range requests to only
8091
read the table of contents of the zip file). This sort of calculation is also
8192
currently repeated by everyone independently instead of having the metadata
82-
hosted by a central index server like PyPI. It also doesn't work for sdists as
83-
the structure of the wheel isn't known yet, and so inferring the structure of
84-
the code installed isn't known yet. As well, these solutions are not
93+
hosted by a central index server like PyPI. It also doesn't work for sdists
94+
as the structure of the wheel isn't known yet, and so inferring the structure
95+
of the code installed isn't known yet. As well, these solutions are not
8596
necessarily accurate as it is based on inference instead of being explicitly
8697
provided by the project owners.
8798

@@ -93,68 +104,54 @@ Because this PEP introduces a new field to the core metadata, it bumps the
93104
latest core metadata version to 2.5.
94105

95106
The ``Import-Name`` field is a "multiple uses" field. Each entry of
96-
``Import-Name`` represents an importable name that the project provides. The
97-
names provided MUST be importable via *some* artifact the project provides
98-
for that version, i.e. the metadata MUST be consistent across all sdists and
99-
wheels for a project release to avoid having to read every file to find
100-
variances. It also avoids having to declare this field as dynamic in an
101-
sdist due to the import names varying across wheels. This does imply that the
102-
information isn't specific to the distribution artifact it is found in, but
103-
for the release version the distribution artifact belongs to.
104-
105-
The names provided MUST be one of the following:
106-
107-
- Highest-level, regular packages
108-
- Top-level modules
109-
- The submodules and regular subpackages within implicit namespace packages
110-
111-
provided by the project. This makes the vast majority of projects only
112-
needing a single ``Import-Name`` entry which represents the top-level,
113-
regular package the project provides. But it also allows for implicit
114-
namespace packages to be able to differentiate among themselves (e.g., it
115-
avoids having all projects contributing to the ``azure`` namespace via an
116-
implicit namespace package all having ``azure`` as their entry for
117-
``Import-Name``, but instead a more accurate entry like
118-
``azure.mgmt.search``)
107+
``Import-Name`` MUST be a valid import name. The names specified in
108+
``Import-Name`` MUST be importable when the project is installed on *some*
109+
platform for the same version of the project (i.e. the metadata MUST be
110+
consistent across all sdists and wheels for a project release). This does
111+
imply that the information isn't specific to the distribution artifact it is
112+
found in, but for the release version the distribution artifact belongs to.
113+
114+
Projects are not expected to list every single import name that is provided.
115+
Instead, projects SHOULD list the highest-level/shortest import name that the
116+
project would "own" when installed. For example, if you install a project
117+
that has a single package named ``myproj`` which itself has multiple
118+
submodules, the expectation is only ``myproj`` would be listed in
119+
``Import-Name`` and not every submodule. If a project is part of a namespace
120+
package named ``ns`` and it provides a subpackage called ``ns.myproj`` (i.e.
121+
``ns.myproj.__init__`` exists), then ``ns.myproj`` should be listed in
122+
``Import-Name``, but NOT ``ns`` alone as that is not "owned" by the project
123+
upon installation (i.e. other projects can be installed which also contribute to
124+
``ns``).
119125

120126
If a project chooses not to provide any ``Import-Name`` entries, tools MAY
121-
assume the import name matches the project name.
122-
123-
Project owners MUST specify accurate information when provided and SHOULD be
124-
exhaustive in what they provide. Project owners SHOULD NOT filter out names
125-
that they consider private. This is because even "private" names can be
126-
imported by anyone and can "take up space" in the namespace of the
127-
environment. Tools consuming the metadata SHOULD consider the information
128-
provided in ``Import-Name`` as accurate, but not exhaustive.
127+
assume the import name matches the project name (including de-normalization of
128+
the project name, e.g. ``my-proj`` as ``my_proj``).
129129

130130
The :ref:`declaring-project-metadata` will gain an ``import-names`` key. It
131131
will be an array of strings that stores what will be written out to
132132
``Import-Name``. Build back-ends MAY support dynamically calculating the
133-
value on the user's behalf if desired, if the user declares the key to be
134-
dynamic.
133+
value on the user's behalf if desired, if the user declares the key in
134+
``project.dynamic``.
135135

136136

137137
Examples
138138
--------
139139

140140
`In httpx 0.28.1
141-
<https://pypi-browser.org/package/httpx/httpx-0.28.1-py3-none-any.whl>`__
142-
there would be only a single entry for the ``httpx`` package as it's a
143-
regular package and there are no other regular packages or modules at the top
144-
of the project.
141+
<https://pypi-browser.org/package/httpx/httpx-0.28.1-py3-none-any.whl>`__ ,
142+
an entry for the ``httpx`` package.
145143

146144
`In pytest 8.3.5
147145
<https://pypi-browser.org/package/pytest/pytest-8.3.5-py3-none-any.whl>`__
148-
there would be 3 entries:
146+
there would be 3 expected entries:
149147

150-
1. ``_pytest`` (a top-level, regular package)
151-
2. ``py`` (a top-level module)
152-
3. ``pytest`` (a top-level, regular package)
148+
1. ``_pytest``
149+
2. ``py``
150+
3. ``pytest``
153151

154152
In `azure-mgmt-search 9.1.0
155153
<https://pypi-browser.org/package/azure-mgmt-search/azure_mgmt_search-9.1.0-py3-none-any.whl>`__,
156-
there would be a single entry for ``azure.mgmt.search`` as ``azure`` and
157-
``azure.mgmt`` are implicit namespace packages.
154+
there should be a single entry for ``azure.mgmt.search``.
158155

159156

160157
Backwards Compatibility
@@ -236,6 +233,19 @@ In the end a `poll
236233
held and the approach this PEP takes won out.
237234

238235

236+
Be more prescriptive in what projects specify
237+
---------------------------------------------
238+
239+
An earlier version of this PEP was much more strict in what could be put into
240+
``Import-Name``. This included turning some "SHOULD" guidelines into "MUST"
241+
requirements and being specific about how to calculate what a project "owned".
242+
In the end it was decided that was too restrictive and risked being implemented
243+
incorrectly or the spec being unexpectedy too strict.
244+
245+
Since the metadata was never expected to be exhaustive as it can't be verified
246+
to be, the looser spec that is currently in this PEP was chosen instead.
247+
248+
239249
Open Issues
240250
===========
241251

@@ -258,3 +268,4 @@ Copyright
258268

259269
This document is placed in the public domain or under the
260270
CC0-1.0-Universal license, whichever is more permissive.
271+
CC0-1.0-Universal license, whichever is more permissive.

0 commit comments

Comments
 (0)