Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 33 additions & 24 deletions peps/pep-0794.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ packaging to include two new, repeatable fields named ``Import-Name`` and
``Import-Namespace`` to record the import names that a project provides once
installed. New keys named ``import-names`` and ``import-namespaces`` will be
added to the ``[project]`` table in ``pyproject.toml`` for providing the values
for the new core metadata field. This also leads to the introduction of core
for the new core metadata fields. This also leads to the introduction of core
metadata version 2.5.


Expand All @@ -27,7 +27,7 @@ Motivation

In Python packaging there is no requirement that a project name match the
name(s) that you can import for that project. As such, there is no clean,
easy, accurate way to go from import name to project name and vice-versa.
easy, accurate way to go from import name to project name and vice versa.
This can make it difficult for tools that try to help people in discovering
the right project to install when they know the import name or knowing what
import names a project will provide once installed.
Expand All @@ -48,7 +48,7 @@ There is also no easy way to know whether installing two projects will conflict
with one another based on the import names they provide. For instance, if two
different projects have a ``_utils`` module, installing both projects will lead
to a clash as one project's ``_utils`` module would take precedence over the
other project's version by overwriting the other project's file; this issue
other's, by overwriting the other project's file; this issue
has been `seen in the wild <https://github.com/astral-sh/uv/pull/13437>`__.

It may also help with spam detection. If a project specifies the same import
Expand Down Expand Up @@ -80,16 +80,16 @@ version and not unique per released file for the same version.

This PEP is not overly strict on what to (not) list in the proposed metadata on
purpose. Having build back-ends verify that a project is accurately following
a specification that is somehow strict about what can be listed would be near
a specification that is somehow strict about what can be listed would be nearly
impossible to get right due to how flexible Python's import system is. As such,
this PEP only requires that valid import names be used and that projects don't
lie (and it is acknowledged the latter requirements cannot be validated
lie (and it is acknowledged the latter requirement cannot be validated
programmatically). Projects do, though, need to account for all levels of the
names they list (e.g. you can't list ``a.b.c`` and not account for ``a`` and
``a.b``).

Various other attempts have been made to solve this, but they all have to
make various trade-offs. For instance, one could download every wheel for
make trade-offs. For instance, one could download every wheel for
every project release and look at what files are provided via the
:ref:`packaging:binary-distribution-format`, but that's a lot of CPU and
bandwidth for something that is static information (although tricks can be
Expand All @@ -99,10 +99,9 @@ currently repeated by everyone independently instead of having the metadata
hosted by a central index server like PyPI. It also doesn't work for sdists
as the structure of the wheel isn't known yet, and so inferring the structure
of the code installed isn't possible. As well, these solutions are not
necessarily accurate as it is based on inference instead of being explicitly
necessarily accurate as they are based on inference instead of being explicitly
provided by the project owners. All of these accuracy issues affect even having
an index hosting the information to avoid the compute costs of gathering the
information.
an index host the information to avoid the compute costs of gathering it.


Specification
Expand All @@ -116,7 +115,7 @@ Each entry of both fields MUST be a valid import name. The names specified MUST
be importable when the project is installed on *some* platform for the same
version of the project (e.g. the metadata MUST be consistent across all sdists
and wheels for a project release). This does imply that the information isn't
specific to the distribution artifact it is found in, but for the release
specific to the distribution artifact it is found in, but to the release
version the distribution artifact belongs to.

``Import-Name`` lists import names which a project, when installed, would
Expand All @@ -138,27 +137,37 @@ Projects SHOULD list all the shortest import names that are exclusively provided
by a project which would cover all import name scenarios. If any of the shortest
names are dotted names, all intervening names from that name to the top-level
name should also be listed appropriately in ``Import-Namespace`` and/or
``Import-Names``. For instance, a project which is a single package named
``Import-Name``. For instance, a project which is a single package named
``spam`` with multiple submodules would only list
``project.import-names = ["spam"]``. A project that lists ``spam.bacon.eggs``
would also need to account for ``spam`` and ``spam.bacon`` appropriately in
``import-names`` and ``import-namespaces``. Listing all names acts as a check
that the intent of the import names is as expected.

If a project lists the same name in both ``Import-Name`` and
``Import-Namespace``, then tools MUST raise an error due to ambiguity; this also
applies to ``import-names`` and ``import-namespaces``, respectively.

Tools SHOULD raise an error when two projects that are to be installed list
names that overlap in each others' ``Import-Name`` entries. This is to avoid
names that overlap in each other's ``Import-Name`` entries. This is to avoid
projects unexpectedly shadowing another project's code. The same applies to when
a project has an entry in ``Import-Name`` that overlaps with another project's
``Import-Namespace`` entries.
``Import-Namespace`` entries. This does not apply to overlapping
``Import-Namespace`` entries as that's the purpose of namespace packages.

Projects MAY leave ``Import-Name`` and ``Import-Namespace`` out of the core
metadata for a project. In that instance, tools SHOULD assume that when the
core metadata is 2.5 or newer that the normalized project name when converted to
an import name would be an entry in ``Import-Name`` (i.e. ``-`` substituted for
``-`` in the normalized project name). This is deemed reasonable as this will
core metadata is 2.5 or newer, the normalized project name, when converted to
an import name, would be an entry in ``Import-Name`` (i.e. ``-`` substituted for
``_`` in the normalized project name). This is deemed reasonable as this will
only occur for projects that make a new release once their build back-end
supports core metadata 2.5 or newer as proposed by this PEP.

Projects MAY set ``import-names`` or ``import-namespaces`` -- as well as
``Import-Name`` or ``Import-Namespace``, respectively -- to the normalized
import name of the project to explicitly declare that the project's name
is also the import name.


Examples
--------
Expand Down Expand Up @@ -222,8 +231,8 @@ otherwise the name goes into ``project.import-names``.
Users of projects don't necessarily need to know about this new metadata.
While they may be exposed to it via tooling, the details of where that data
came from isn't critical. It's possible they may come across it if an index
server exposed it (e.g., listed the values from ``Import-Name`` and marked
whether the file structure backed up the claims the metadata makes), but that
server exposes it (e.g., lists the values from ``Import-Name`` and marks
whether the file structure backs up the claims the metadata makes), but that
still wouldn't require users to know the technical details of this PEP.


Expand All @@ -242,7 +251,7 @@ Infer the value for ``Import-Namespace``

A previous version of this PEP inferred what would have been the values for
``Import-Namespace`` based on dotted names in ``Import-Name``. It was decided
that it would better to be explicit not only to avoid mistakes by accidentally
that it would be better to be explicit not only to avoid mistakes by accidentally
listing something that would be interpreted as an implicit namespace, but it
also made the data more self-documenting.

Expand All @@ -251,7 +260,7 @@ Require that names listed in ``Import-Namespace`` never be contained by a name i
-------------------------------------------------------------------------------------------------

The way Python's import system works by default means that it isn't possible to
have an import name contain an namespace. But Python's import system is flexible
have an import name contain a namespace. But Python's import system is flexible
enough that user code could make that possible. As such, the requirement that
tools error out if an import name contained a namespace name --
``import-names = ["spam"]`` and ``import-namespaces = ["spam.bacon"]`` -- was
Expand All @@ -272,7 +281,7 @@ made to go with a new field.
Name the field ``Namespace``
----------------------------

While the term "namespace" name is technically accurate from an import
While the term "namespace" is technically accurate from an import
perspective, it could be confused with implicit namespace packages.


Expand All @@ -284,7 +293,7 @@ During `discussions about a pre-PEP version
PEP, it was suggested that the ``RECORD`` file from wheels be served from
index servers instead of this new metadata. That would have the benefit of
being implementable immediately. But in order to provide the equivalent
information there would be necessary inference based on the file structure of
information, inference would be necessary based on the file structure of
what would be installed by the wheel. That could lead to inaccurate
information. It also doesn't support sdists.

Expand All @@ -300,7 +309,7 @@ An earlier version of this PEP was much more strict in what could be put into
``Import-Name``. This included turning some "SHOULD" guidelines into "MUST"
requirements and being specific about how to calculate what a project "owned".
In the end it was decided that was too restrictive and risked being implemented
incorrectly or the spec being unexpectedy too strict.
incorrectly or the spec being unexpectedly too strict.

Since the metadata was never expected to be exhaustive as it can't be verified
to be, the looser spec that is currently in this PEP was chosen instead.
Expand All @@ -315,7 +324,7 @@ N/A
Acknowledgments
===============

Thanks to HeeJae Chang for ~~complaining about~~ bringing up regularly the
Thanks to HeeJae Chang for ~~complaining about~~ regularly bringing up the
usefulness that this metadata would provide. Thanks to Josh Cannon (no
relation) for reviewing drafts of this PEP and providing feedback. Also,
thanks to everyone who participated in a `previous discussion
Expand Down