diff --git a/peps/pep-0794.rst b/peps/pep-0794.rst index ba1dbf4248f..748c20eb36e 100644 --- a/peps/pep-0794.rst +++ b/peps/pep-0794.rst @@ -17,9 +17,9 @@ This PEP proposes extending the core metadata specification for Python 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 fields. This also leads to the introduction of core -metadata version 2.5. +added to the ``[project]`` table in :file:`pyproject.toml` for providing the +values for the new core metadata fields. This also leads to the introduction of +core metadata version 2.5. Motivation @@ -74,9 +74,19 @@ projects to only have to check a single file's core metadata to get all possible import names instead of checking all the released files. This also means one does not need to worry if a file is missing when reading the core metadata or one can work solely from an sdist if the metadata is provided. As -well, it simplifies having ``project.import-names`` and ``project.import-namespaces`` -keys in ``pyproject.toml`` by having it be consistent for the entire project -version and not unique per released file for the same version. +well, it simplifies having ``project.import-names`` and +``project.import-namespaces`` keys in :file:`pyproject.toml` by having it be +consistent for the entire project version and not unique per released file for +the same version. + +A distribution file containing modules and packages can have any combination of +public and private APIs at the module/package level. Distribution files can also +contain no modules or packages of any kind. Being able to distinguish between +the situations all have various tool uses that could be beneficial to users. For +instance, knowing all import names regardless of whether they are public or +private helps detect clashes at install time. But knowing what is explicitly +public or private allows tools such as editors to not suggest private import +names as part of auto-complete. 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 @@ -111,12 +121,17 @@ Because this PEP introduces a new field to the core metadata, it bumps the latest core metadata version to 2.5. The ``Import-Name`` and ``Import-Namespace`` fields are "multiple uses" fields. -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 to the release -version the distribution artifact belongs to. +Each entry of both fields MUST be a valid import name or can be empty in the +case of ``Import-Name``. Any 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 to the release version the distribution artifact belongs to. + +An import name MAY be followed by a semicolon and the term "private" (e.g. +``; private``). This signals to tools that the import name is not part of the +public API for the project. Any number of spaces surrounding the ``;`` is +allowed. ``Import-Name`` lists import names which a project, when installed, would *exclusively* provide (i.e. if two projects were installed with the same import @@ -142,7 +157,9 @@ name should also be listed appropriately in ``Import-Namespace`` and/or ``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. +that the intent of the import names is as expected. As well, projects SHOULD +list all import names, public or private, using the ``; private`` modifier +as appropriate. 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 @@ -158,7 +175,7 @@ a project has an entry in ``Import-Name`` that overlaps with another project's 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, the normalized project name, when converted to -an import name, would be an entry in ``Import-Name`` (i.e. ``-`` substituted for +an import name, would be an entry in ``Import-Name`` (i.e. ``-`` replaced with ``_`` 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. @@ -168,6 +185,13 @@ Projects MAY set ``import-names`` or ``import-namespaces`` -- as well as import name of the project to explicitly declare that the project's name is also the import name. +Projects MAY set ``import-names`` an empty array and not set +``import-namespaces`` at all in a :file:`pyproject.toml` file (e.g. +``import-names = []``). To match this, projects MAY have an empty +``Import-Name`` field in their metadata. This represents a project with NO +import names, public or private (i.e. there are no Python modules of any kind +in the distribution file). + Examples -------- @@ -225,8 +249,8 @@ projects provide for importing. If their project name matches the module or package name their project provides they don't have to do anything. If there is a difference, though, they should record all the import names their project provides, using the shortest names possible. If any of the names are implicit -namespaces, those go into ``project.import-namespaces`` in ``pyproject.toml``, -otherwise the name goes into ``project.import-names``. +namespaces, those go into ``project.import-namespaces`` in +:file:`pyproject.toml`, 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