Skip to content

Commit c97a3ec

Browse files
authored
Merge pull request #1927 from brettcannon/pep-794
Add PEP 794: Import name metadata
2 parents 769d374 + d470a9f commit c97a3ec

File tree

2 files changed

+215
-20
lines changed

2 files changed

+215
-20
lines changed

source/specifications/core-metadata.rst

Lines changed: 120 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
Core metadata specifications
77
============================
88

9-
This page describes version 2.4, approved in August 2024.
9+
This page describes version 2.5, approved in September 2025.
1010

1111
Fields defined in the following specification should be considered valid,
1212
complete and not subject to change. The required fields are:
@@ -50,7 +50,7 @@ Metadata-Version
5050
.. versionadded:: 1.0
5151

5252
Version of the file format; legal values are "1.0", "1.1", "1.2", "2.1",
53-
"2.2", "2.3", and "2.4".
53+
"2.2", "2.3", "2.4", and "2.5".
5454

5555
Automated tools consuming metadata SHOULD warn if ``metadata_version`` is
5656
greater than the highest version they support, and MUST fail if
@@ -724,6 +724,101 @@ user SHOULD be warned and the value ignored to avoid ambiguity. Tools MAY choose
724724
to raise an error when reading an invalid name for older metadata versions.
725725

726726

727+
.. _core-metadata-import-name:
728+
729+
Import-Name (multiple use)
730+
==========================
731+
732+
.. versionadded:: 2.5
733+
734+
A string containing an import name that the project exclusively provides when
735+
installed. The specified import name MUST be a valid Python identifier or can
736+
be empty. The import names listed in this field MUST be importable when the
737+
project is installed on *some* platform for the same version of the project.
738+
This implies that the metadata MUST be consistent across all sdists and wheels
739+
for a project release.
740+
741+
An import name MAY be followed by a semicolon and the term "private"
742+
(e.g. ``; private``) with any amount of whitespace surrounding the semicolon.
743+
This signals to tools that the import name is not part of the public API for
744+
the project.
745+
746+
Projects SHOULD list all the shortest import names that are exclusively provided
747+
by the project. If any of the shortest names are dotted names, all intervening
748+
names from that name to the top-level name should also be listed appropriately
749+
in ``Import-Name`` and/or ``Import-Namespace``.
750+
751+
If a project lists the same name in both ``Import-Name`` and
752+
``Import-Namespace``, tools MUST raise an error due to ambiguity.
753+
754+
Tools SHOULD raise an error when two projects that are about to be installed
755+
list names that overlap in each other's ``Import-Name`` entries, or when a
756+
project has an entry in ``Import-Name`` that overlaps with another project's
757+
``Import-Namespace`` entries. This is to avoid projects unexpectedly shadowing
758+
another project's code. Tools MAY warn or raise an error when installing a
759+
project into a preexisting environment where there is import name overlap with
760+
a project that is already installed.
761+
762+
Projects MAY have an empty ``Import-Name`` field in their metadata to represent
763+
a project with no import names (i.e. there are no Python modules of any kind in
764+
the distribution file).
765+
766+
Since projects MAY have no ``Import-Name`` metadata (either because the
767+
project uses an older metadata version, or because it didn't specify any), then
768+
tools have no information about what names the project provides. However, in
769+
practice the majority of projects have their project name match what their
770+
import name would be. As such, it is a reasonable assumption to make that a
771+
project name that is normalized in some way to an import name
772+
(e.g. ``packaging.utils.canonicalize_name(name, validate=True).replace("-", "_")``)
773+
can be used if some answer is needed.
774+
775+
Examples::
776+
777+
Import-Name: PIL
778+
Import-Name: _private_module ; private
779+
Import-Name: zope.interface
780+
Import-Name:
781+
782+
783+
.. _core-metadata-import-namespace:
784+
785+
Import-Namespace (multiple use)
786+
===============================
787+
788+
.. versionadded:: 2.5
789+
790+
A string containing an import name that the project provides when installed, but
791+
not exclusively. The specified import name MUST be a valid Python identifier.
792+
This field is used for namespace packages where multiple projects can contribute
793+
to the same import namespace. Projects all listing the same import name in
794+
``Import-Namespace`` can be installed together without shadowing each other.
795+
796+
An import name MAY be followed by a semicolon and the term "private" (e.g.
797+
``; private``) with any amount of whitespace surrounding the semicolon. This
798+
signals to tools that the import name is not part of the public API for the
799+
project.
800+
801+
Projects SHOULD list all the shortest import names that are exclusively provided
802+
by the project. If any of the shortest names are dotted names, all intervening
803+
names from that name to the top-level name should also be listed appropriately
804+
in ``Import-Name`` and/or ``Import-Namespace``.
805+
806+
The import names listed in this field MUST be importable when the project is
807+
installed on *some* platform for the same version of the project. This implies
808+
that the metadata MUST be consistent across all sdists and wheels for a project
809+
release.
810+
811+
If a project lists the same name in both ``Import-Name`` and
812+
``Import-Namespace``, tools MUST raise an error due to ambiguity.
813+
814+
Note that ``Import-Namespace`` CANNOT be empty like ``Import-Name``.
815+
816+
Examples::
817+
818+
Import-Namespace: zope
819+
Import-Name: _private_module ; private
820+
821+
727822
Rarely Used Fields
728823
==================
729824

@@ -939,37 +1034,42 @@ Example::
9391034
History
9401035
=======
9411036

942-
- October 2025: Clarified that ``License-Expression`` applies to the containing
943-
distribution file and not the project itself.
944-
945-
- August 2025: Clarified that ``Dynamic`` only affects how fields
946-
must be treated when building a wheel from a sdist, not when modifying
947-
a wheel.
1037+
- March 2001: Core metadata 1.0 was approved through :pep:`241`.
9481038

949-
- August 2024: Core metadata 2.4 was approved through :pep:`639`.
1039+
- April 2003: Core metadata 1.1 was approved through :pep:`314`.
9501040

951-
- Added the ``License-Expression`` field.
952-
- Added the ``License-File`` field.
1041+
- February 2010: Core metadata 1.2 was approved through :pep:`345`.
9531042

954-
- March 2022: Core metadata 2.3 was approved through :pep:`685`.
1043+
- February 2018: Core metadata 2.1 was approved through :pep:`566`.
9551044

956-
- Restricted extra names to be normalized.
1045+
- Added ``Description-Content-Type`` and ``Provides-Extra``.
1046+
- Added canonical method for transforming metadata to JSON.
1047+
- Restricted the grammar of the ``Name`` field.
9571048

9581049
- October 2020: Core metadata 2.2 was approved through :pep:`643`.
9591050

9601051
- Added the ``Dynamic`` field.
9611052

962-
- February 2018: Core metadata 2.1 was approved through :pep:`566`.
1053+
- March 2022: Core metadata 2.3 was approved through :pep:`685`.
9631054

964-
- Added ``Description-Content-Type`` and ``Provides-Extra``.
965-
- Added canonical method for transforming metadata to JSON.
966-
- Restricted the grammar of the ``Name`` field.
1055+
- Restricted extra names to be normalized.
9671056

968-
- February 2010: Core metadata 1.2 was approved through :pep:`345`.
1057+
- August 2024: Core metadata 2.4 was approved through :pep:`639`.
9691058

970-
- April 2003: Core metadata 1.1 was approved through :pep:`314`:
1059+
- Added the ``License-Expression`` field.
1060+
- Added the ``License-File`` field.
9711061

972-
- March 2001: Core metadata 1.0 was approved through :pep:`241`.
1062+
- August 2025: Clarified that ``Dynamic`` only affects how fields
1063+
must be treated when building a wheel from a sdist, not when modifying
1064+
a wheel.
1065+
1066+
- September 2025: Core metadata 2.5 was approved through :pep:`794`.
1067+
1068+
- Added the ``Import-Name`` field.
1069+
- Added the ``Import-Namespace`` field.
1070+
1071+
- October 2025: Clarified that ``License-Expression`` applies to the containing
1072+
distribution file and not the project itself.
9731073

9741074
----
9751075

source/specifications/pyproject-toml.rst

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ The complete list of keys allowed in the ``[project]`` table are:
136136
- ``dynamic``
137137
- ``entry-points``
138138
- ``gui-scripts``
139+
- ``import-names``
140+
- ``import-namespaces``
139141
- ``keywords``
140142
- ``license``
141143
- ``license-files``
@@ -472,6 +474,97 @@ matching :ref:`Provides-Extra <core-metadata-provides-extra>`
472474
metadata.
473475

474476

477+
.. _pyproject-toml-import-names:
478+
479+
``import-names``
480+
----------------
481+
482+
- TOML_ type: array of strings
483+
- Corresponding :ref:`core metadata <core-metadata>` field:
484+
:ref:`Import-Name <core-metadata-import-name>`
485+
486+
An array of strings specifying the import names that the project exclusively
487+
provides when installed. Each string MUST be a valid Python identifier or can
488+
be empty. An import name MAY be followed by a semicolon and the term "private"
489+
(e.g. ``"; private"``) with any amount of whitespace surrounding the semicolon.
490+
491+
Projects SHOULD list all the shortest import names that are exclusively provided
492+
by the project. If any of the shortest names are dotted names, all intervening
493+
names from that name to the top-level name should also be listed appropriately
494+
in ``import-names`` and/or ``import-namespaces``. For instance, a project which
495+
is a single package named spam with multiple submodules would only list
496+
``project.import-names = ["spam"]``. A project that lists ``spam.bacon.eggs``
497+
would also need to account for ``spam`` and ``spam.bacon`` appropriately in
498+
``import-names`` and ``import-namespaces``. Listing all names acts as a check
499+
that the intent of the import names is as expected. As well, projects SHOULD
500+
list all import names, public or private, using the ``; private`` modifier as
501+
appropriate.
502+
503+
If a project lists the same name in both ``import-names`` and
504+
``import-namespaces``, then tools MUST raise an error due to ambiguity.
505+
506+
Projects MAY set ``import-names`` to an empty array to represent a project with
507+
no import names (i.e. there are no Python modules of any kind in the
508+
distribution file).
509+
510+
Build back-ends MAY support dynamically calculating the value if the user
511+
declares the key in ``project.dynamic``.
512+
513+
Examples:
514+
515+
.. code-block:: toml
516+
517+
[project]
518+
name = "pillow"
519+
import-names = ["PIL"]
520+
521+
.. code-block:: toml
522+
523+
[project]
524+
name = "myproject"
525+
import-names = ["mypackage", "_private_module ; private"]
526+
527+
528+
.. _pyproject-toml-import-namespaces:
529+
530+
``import-namespaces``
531+
---------------------
532+
533+
- TOML_ type: array of strings
534+
- Corresponding :ref:`core metadata <core-metadata>` field:
535+
:ref:`Import-Namespace <core-metadata-import-namespace>`
536+
537+
An array of strings specifying the import names that the project provides when
538+
installed, but not exclusively. Each string MUST be a valid Python identifier.
539+
An import name MAY be followed by a semicolon and the term "private" (e.g.
540+
``"; private"``) with any amount of whitespace surrounding the semicolon. Note
541+
that unlike ``import-names``, ``import-namespaces`` CANNOT be an empty array.
542+
543+
Projects SHOULD list all the shortest import names that are exclusively provided
544+
by the project. If any of the shortest names are dotted names, all intervening
545+
names from that name to the top-level name should also be listed appropriately
546+
in ``import-names`` and/or ``import-namespaces``.
547+
548+
This field is used for namespace packages where multiple projects can contribute
549+
to the same import namespace. Projects all listing the same import name in
550+
``import-namespaces`` can be installed together without shadowing each other.
551+
552+
If a project lists the same name in both ``import-names`` and
553+
``import-namespaces``, then tools MUST raise an error due to ambiguity.
554+
555+
Build back-ends MAY support dynamically calculating the value if the user
556+
declares the key in ``project.dynamic``.
557+
558+
Example:
559+
560+
.. code-block:: toml
561+
562+
[project]
563+
name = "zope-interface"
564+
import-namespaces = ["zope"]
565+
import-names = ["zope.interface"]
566+
567+
475568
.. _pyproject-toml-dynamic:
476569
.. _declaring-project-metadata-dynamic:
477570

@@ -549,5 +642,7 @@ History
549642
- September 2025: Clarity that the ``license`` key applies to all distribution
550643
files generated from the :file:`pyproject.toml` file.
551644

645+
- October 2025: The ``import-names`` and ``import-namespaces`` keys were added
646+
through :pep:`794`.
552647

553648
.. _TOML: https://toml.io

0 commit comments

Comments
 (0)