Skip to content
Open
Show file tree
Hide file tree
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
134 changes: 117 additions & 17 deletions source/specifications/core-metadata.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
Core metadata specifications
============================

This page describes version 2.4, approved in August 2024.
This page describes version 2.5, approved in September 2025.

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

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

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


.. _core-metadata-import-name:

Import-Name (multiple use)
===========================

.. versionadded:: 2.5

A string containing an import name that the project exclusively provides when
installed. The specified import name MUST be a valid Python identifier or can
be empty. The import names listed in this field MUST be importable when the
project is installed on *some* platform for the same version of the project.
This implies that the metadata MUST be consistent across all sdists and wheels
for a project release.

An import name MAY be followed by a semicolon and the term "private"
(e.g. ``; private``) with any amount of whitespace surrounding the semicolon.
This signals to tools that the import name is not part of the public API for
the project.

Projects SHOULD list all the shortest import names that are exclusively provided
by the project. 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-Name`` and/or ``Import-Namespace``.

If a project lists the same name in both ``Import-Name`` and
``Import-Namespace``, tools MUST raise an error due to ambiguity.

Tools SHOULD raise an error when two projects that are about to be installed
list names that overlap in each other's ``Import-Name`` entries, or when a
project has an entry in ``Import-Name`` that overlaps with another project's
``Import-Namespace`` entries. This is to avoid projects unexpectedly shadowing
another project's code. Tools MAY warn or raise an error when installing a
project into a preexisting environment where there is import name overlap with
a project that is already installed.

Projects MAY have an empty ``Import-Name`` field in their metadata to represent
a project with no import names (i.e. there are no Python modules of any kind in
the distribution file).

Since projects MAY have no ``Import-Name`` metadata (either because the
project uses an older metadata version, or because it didn't specify any), then
tools have no information about what names the project provides. However, in
practice the majority of projects have their project name match what their
import name would be. As such, it is a reasonable assumption to make that a
project name that is normalized in some way to an import name
(e.g. ``packaging.utils.canonicalize_name(name, validate=True).replace("-", "_")``)
can be used if some answer is needed.

Examples::

Import-Name: PIL
Import-Name: _private_module ; private
Import-Name: zope.interface
Import-Name:


.. _core-metadata-import-namespace:

Import-Namespace (multiple use)
================================

.. versionadded:: 2.5

A string containing an import name that the project provides when installed, but
not exclusively. The specified import name MUST be a valid Python identifier.
This field is used for namespace packages where multiple projects can contribute
to the same import namespace. Projects all listing the same import name in
``Import-Namespace`` can be installed together without shadowing each other.

An import name MAY be followed by a semicolon and the term "private" (e.g.
``; private``) with any amount of whitespace surrounding the semicolon. This
signals to tools that the import name is not part of the public API for the
project.

Projects SHOULD list all the shortest import names that are exclusively provided
by the project. 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-Name`` and/or ``Import-Namespace``.

The import names listed in this field MUST be importable when the project is
installed on *some* platform for the same version of the project. This implies
that the metadata MUST be consistent across all sdists and wheels for a project
release.

If a project lists the same name in both ``Import-Name`` and
``Import-Namespace``, tools MUST raise an error due to ambiguity.

Note that ``Import-Namespace`` CANNOT be empty like ``Import-Name``.

Examples::

Import-Namespace: zope
Import-Name: _private_module ; private


Rarely Used Fields
==================

Expand Down Expand Up @@ -933,34 +1028,39 @@ Example::
History
=======

- August 2025: Clarified that ``Dynamic`` only affects how fields
must be treated when building a wheel from a sdist, not when modifying
a wheel.
- March 2001: Core metadata 1.0 was approved through :pep:`241`.

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

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

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

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

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

- Added the ``Dynamic`` field.

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

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

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

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

- March 2001: Core metadata 1.0 was approved through :pep:`241`.
- August 2025: Clarified that ``Dynamic`` only affects how fields
must be treated when building a wheel from a sdist, not when modifying
a wheel.

- September 2025: Core metadata 2.5 was approved through :pep:`794`.

- Added the ``Import-Name`` field.
- Added the ``Import-Namespace`` field.

----

Expand Down
96 changes: 96 additions & 0 deletions source/specifications/pyproject-toml.rst
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ The complete list of keys allowed in the ``[project]`` table are:
- ``dynamic``
- ``entry-points``
- ``gui-scripts``
- ``import-names``
- ``import-namespaces``
- ``keywords``
- ``license``
- ``license-files``
Expand Down Expand Up @@ -466,6 +468,97 @@ matching :ref:`Provides-Extra <core-metadata-provides-extra>`
metadata.


.. _pyproject-toml-import-names:

``import-names``
----------------

- TOML_ type: array of strings
- Corresponding :ref:`core metadata <core-metadata>` field:
:ref:`Import-Name <core-metadata-import-name>`

An array of strings specifying the import names that the project exclusively
provides when installed. Each string MUST be a valid Python identifier or can
be empty. An import name MAY be followed by a semicolon and the term "private"
(e.g. ``"; private"``) with any amount of whitespace surrounding the semicolon.

Projects SHOULD list all the shortest import names that are exclusively provided
by the project. 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-names`` and/or ``import-namespaces``. 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. 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-names`` and
``import-namespaces``, then tools MUST raise an error due to ambiguity.

Projects MAY set ``import-names`` to an empty array to represent a project with
no import names (i.e. there are no Python modules of any kind in the
distribution file).

Build back-ends MAY support dynamically calculating the value if the user
declares the key in ``project.dynamic``.

Examples:

.. code-block:: toml

[project]
name = "pillow"
import-names = ["PIL"]

.. code-block:: toml

[project]
name = "myproject"
import-names = ["mypackage", "_private_module ; private"]


.. _pyproject-toml-import-namespaces:

``import-namespaces``
---------------------

- TOML_ type: array of strings
- Corresponding :ref:`core metadata <core-metadata>` field:
:ref:`Import-Namespace <core-metadata-import-namespace>`

An array of strings specifying the import names that the project provides when
installed, but not exclusively. Each string MUST be a valid Python identifier.
An import name MAY be followed by a semicolon and the term "private" (e.g.
``"; private"``) with any amount of whitespace surrounding the semicolon. Note
that unlike ``import-names``, ``import-namespaces`` CANNOT be an empty array.

Projects SHOULD list all the shortest import names that are exclusively provided
by the project. 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-names`` and/or ``import-namespaces``.

This field is used for namespace packages where multiple projects can contribute
to the same import namespace. Projects all listing the same import name in
``import-namespaces`` can be installed together without shadowing each other.

If a project lists the same name in both ``import-names`` and
``import-namespaces``, then tools MUST raise an error due to ambiguity.

Build back-ends MAY support dynamically calculating the value if the user
declares the key in ``project.dynamic``.

Example:

.. code-block:: toml

[project]
name = "zope-interface"
import-namespaces = ["zope"]
import-names = ["zope.interface"]


.. _pyproject-toml-dynamic:
.. _declaring-project-metadata-dynamic:

Expand Down Expand Up @@ -540,5 +633,8 @@ History
- December 2024: The ``license`` key was redefined, the ``license-files`` key was
added and ``License::`` classifiers were deprecated through :pep:`639`.

- September 2025: The ``import-names`` and ``import-namespaces`` keys were added
through :pep:`794`.


.. _TOML: https://toml.io
Loading