This PEP depends onPEP 426, which has itself been withdrawn. See thePEP Withdrawal section in that PEP for details.
In the meantime, metadata extensions will continue to be handled as theyhave been for past examples likeentry_points.txt: as additional filesinstalled into metadata directories alongside the mainMETADATA file.
This PEP describes several standard extensions to the Python metadata.
Like all metadata extensions, each standard extension format isindependently versioned. Changing any of the formats requires an updateto this PEP, but does not require an update to the core packaging metadata.
Thepython project on the Python Package Index refers to the CPythonreference interpreter. This namespace is used as the namespace for thestandard metadata extensions.
The currently defined standard extensions are:
python.detailspython.projectpython.integratorpython.exportspython.commandspython.constraintsAll standard extensions are currently at version1.0, and thus theextension_metadata field may be omitted without losing access to anyfunctionality.
python.details extensionThepython.details extension allows for more information to be providedregarding the software distribution.
Thepython.details extension contains four custom subfields:
license: the copyright license for the distributionkeywords: package index keywords for the distributionclassifiers: package index Trove classifiers for the distributiondocument_names: the names of additional metadata filesAll of these fields are optional. Automated tools MUST operate correctly ifa distribution does not provide them, including failing cleanly when anoperation depending on one of these fields is requested.
A short string summarising the license used for this distribution.
Note that distributions that provide this field should still specify anyapplicable license Trove classifiers in theClassifiers field. Evenwhen an appropriate Trove classifier is available, the license summary canbe a good way to specify a particular version of that license, or toindicate any variations or exception to the license.
This field SHOULD contain fewer than 512 characters and MUST contain fewerthan 2048.
This field SHOULD NOT contain any line breaks.
The full license text SHOULD be included as a separate file in the sourcearchive for the distribution. SeeDocument names for details.
Example:
"license":"GPL version 3, excluding DRM provisions"
A list of additional keywords to be used to assist searching for thedistribution in a larger catalog.
Example:
"keywords":["comfy","chair","cushions","too silly","monty python"]
A list of strings, with each giving a single classification valuefor the distribution. Classifiers are described inPEP 301 [2].
Example:
"classifiers":["Development Status :: 4 - Beta","Environment :: Console (Text Based)","License :: OSI Approved :: GNU General Public License v3 (GPLv3)"]
Filenames for supporting documents included in the distribution’sdist-info metadata directory.
The following supporting documents can be named:
description: a file containing a long description of the distributionlicense: a file with the full text of the distribution’s licensechangelog: a file describing changes made to the distributionSupporting documents MUST be included directly in thedist-infodirectory. Directory separators are NOT permitted in document names.
The markup format (if any) for the file is indicated by the file extension.This allows index servers and other automated tools to render includedtext documents correctly and provide feedback on rendering errors, ratherthan having to guess the intended format.
If the filename has no extension, or the extension is not recognised, thedefault rendering format MUST be plain text.
The following markup renderers SHOULD be used for the specified fileextensions:
.txt, no extension, unknown extension.rst.md.adoc,.asc,.asciidoc.html,.htmAutomated tools MAY render one or more of the specified formats as plaintext and MAY render other markup formats beyond those listed.
Automated tools SHOULD NOT make any assumptions regarding the maximum lengthof supporting document content, except as necessary to protect theintegrity of a service.
Example:
"document_names":{"description":"README.rst","license":"LICENSE.rst","changelog":"NEWS"}
python.project extensionThepython.project extension allows for more information to be providedregarding the creation and maintenance of the distribution.
Thepython.project extension contains three custom subfields:
contacts: key contact points for the distributioncontributors: other contributors to the distributionproject_urls: relevant URLs for the distributionDetails on individuals and organisations are recorded as mappings withthe following subfields:
name: the name of an individual or groupemail: an email address (this may be a mailing list)url: a URL (such as a profile page on a source code hosting service)role: one of"author","maintainer" or"contributor"Thename subfield is required, the other subfields are optional.
If no specific role is stated, the default iscontributor.
Email addresses must be in the formlocal-part@domain where thelocal-part may be up to 64 characters long and the entire email addresscontains no more than 254 characters. The formal specification of theformat is inRFC 5322 (sections 3.2.3 and 3.4.1) andRFC 5321, with a morereadable form given in the informationalRFC 3696 and the associated errata.
The defined contributor roles are as follows:
author: the original creator of a distributionmaintainer: the current lead contributor for a distribution, whenthey are not the original creatorcontributor: any other individuals or organizations involved in thecreation of the distributionContact and contributor metadata is optional. Automated tools MUST operatecorrectly if a distribution does not provide it, including failing cleanlywhen an operation depending on one of these fields is requested.
A list of contributor entries giving the recommended contact points forgetting more information about the project.
The example below would be suitable for a project that was in the processof handing over from the original author to a new lead maintainer, whileoperating as part of a larger development group.
Example:
"contacts":[{"name":"Python Packaging Authority/Distutils-SIG","email":"distutils-sig@python.org","url":"https://bitbucket.org/pypa/"},{"name":"Samantha C.","role":"maintainer","email":"dontblameme@example.org"},{"name":"Charlotte C.","role":"author","email":"iambecomingasketchcomedian@example.com"}]
A list of contributor entries for other contributors not already listed ascurrent project points of contact. The subfields within the list elementsare the same as those for the main contact field.
Example:
"contributors":[{"name":"John C."},{"name":"Erik I."},{"name":"Terry G."},{"name":"Mike P."},{"name":"Graeme C."},{"name":"Terry J."}]
A mapping of arbitrary text labels to additional URLs relevant to theproject.
While projects are free to choose their own labels and specific URLs,it is RECOMMENDED that home page, source control, issue tracker anddocumentation links be provided using the labels in the example below.
URL labels MUST be treated as case insensitive by automated tools, but theyare not required to be valid Python identifiers. Any legal JSON string ispermitted as a URL label.
Example:
"project_urls":{"Documentation":"https://distlib.readthedocs.org","Home":"https://bitbucket.org/pypa/distlib","Repository":"https://bitbucket.org/pypa/distlib/src","Tracker":"https://bitbucket.org/pypa/distlib/issues"}
python.integrator extensionStructurally, this extension is largely identical to thepython.projectextension (the extension name is the only difference).
However, where theproject metadata refers to the upstream creatorsof the software, theintegrator metadata refers to the downstreamredistributor of a modified version.
If the software is being redistributed unmodified, then typically thisextension will not be used. However, if the software has been patched (forexample, backporting compatible fixes from a later version, or addressinga platform compatibility issue), then this extension SHOULD be used, anda local version label added to the distribution’s version identifier.
If there are multiple redistributors in the chain, each one just overwritesthis extension with their particular metadata.
python.exports extensionMost Python distributions expose packages and modules for import throughthe Python module namespace. Distributions may also expose otherinterfaces when installed.
Thepython.exports extension contains three custom subfields:
modules: modules exported by the distributionnamespaces: namespace packages that the distribution contributes toexports: other Python interfaces exported by the distributionAn export specifier is a string consisting of a fully qualified name, aswell as an optional extra name enclosed in square brackets. This gives thefollowing four possible forms for an export specifier:
modulemodule:namemodule[requires_extra]module:name[requires_extra]
Note
The jsonschema file currently restricts qualified names using thePython 2 ASCII identifier rules. This may need to be reconsideredgiven the more relaxed identifier rules in Python 3.
The meaning of the subfields is as follows:
module: the module providing the exportname: if applicable, the qualified name of the export within the modulerequires_extra: indicates the export will only work correctly if theadditional dependencies named in the given extra are available in theinstalled environmentNote
I tried this as a mapping with subfields, and it made the examples belowunreadable. While this PEP is mostly for tool use, readability stillmatters to some degree for debugging purposes, and because I expectsnippets of the format to be reused elsewhere.
A list of qualified names of modules and packages that the distributionprovides for import.
Note
The jsonschema file currently restricts qualified names using thePython 2 ASCII identifier rules. This may need to be reconsideredgiven the more relaxed identifier rules in Python 3.
For names that contain dots, the portion of the name before the final dotMUST appear either in the installed module list or in the namespace packagelist.
To help avoid name conflicts, it is RECOMMENDED that distributions providea single top level module or package that matches the distribution name(or a lower case equivalent). This requires that the distribution name alsomeet the requirements of a Python identifier, which are stricter thanthose for distribution names). This practice will also make it easier tofind authoritative sources for modules.
Index servers SHOULD allow multiple distributions to publish the samemodules, but MAY notify distribution authors of potential conflicts.
Installation tools SHOULD report an error when asked to install adistribution that provides a module that is also provided by a different,previously installed, distribution.
Note that attempting to import some declared modules may result in anexception if the appropriate extras are not installed.
Example:
"modules":["chair","chair.cushions","python_sketches.nobody_expects"]
Note
Making this a list of export specifiers instead would allow a distributionto declare when a particular module requires a particular extra in orderto run correctly. On the other hand, there’s an argument to be made thatthat is the point where it starts to become worthwhile to split out aseparate distribution rather than using extras.
A list of qualified names of namespace packages that the distributioncontributes modules to.
Note
The jsonschema file currently restricts qualified names using thePython 2 ASCII identifier rules. This may need to be reconsideredgiven the more relaxed identifier rules in Python 3.
On versions of Python prior to Python 3.3 (which provides native namespacepackage support), installation tools SHOULD emit a suitable__init__.pyfile to properly initialise the namespace rather than using a distributionprovided file.
Installation tools SHOULD emit a warning and MAY emit an error if adistribution declares a namespace package that conflicts with the name ofan already installed module or vice-versa.
Example:
"namespaces":["python_sketches"]
Theexports field is a mapping containing prefixed names as keys. Eachkey identifies an export group containing one or more exports published bythe distribution.
Export group names are defined by distributions that will then make use ofthe published export information in some way. The primary use case is fordistributions that support a plugin model: defining an export group allowsother distributions to indicate which plugins they provide, how theycan be imported and accessed, and which additional dependencies (if any)are needed for the plugin to work correctly.
To reduce the chance of name conflicts, export group names SHOULD use aprefix that corresponds to a module name in the distribution that definesthe meaning of the export group. This practice will also make it easier tofind authoritative documentation for export groups.
Each individual export group is then a mapping of arbitrary non-empty stringkeys to export specifiers. The meaning of export names within an exportgroup is up to the distribution that defines the export group. Creating anappropriate definition for the export name format can allow the importingdistribution to determine whether or not an export is relevant withoutneeding to import every exporting module.
Example:
"exports":{"nose.plugins.0.10":{"chairtest":"chair:NosePlugin"}}
python.commands extensionThepython.commands extension contains three custom subfields:
wrap_console: console wrapper scripts to be generated by the installerwrap_gui: GUI wrapper scripts to be generated by the installerprebuilt: scripts created by the distribution’s build process andinstalled directly to the configured scripts directorywrap_console andwrap_gui are both mappings of script names toexport specifiers. The script names must follow the same naming rules asdistribution names.
The export specifiers for wrapper scripts must refer to either a packagewith a __main__ submodule (if noname subfield is given in the exportspecifier) or else to a callable inside the named module.
Installation tools should generate appropriate wrappers as part of theinstallation process.
Note
Still needs more detail on what “appropriate wrappers” means. For now,refer to what setuptools and zc.buildout generate as wrapper scripts.
prebuilt is a list of script paths, relative to the scripts directory ina wheel file or following installation. They are provided for informationalpurpose only - installing them is handled through the normal processes forfiles created when building a distribution.
Build tools SHOULD mark this extension as requiring handling by installers.
Index servers SHOULD allow multiple distributions to publish the samecommands, but MAY notify distribution authors of potential conflicts.
Installation tools SHOULD report an error when asked to install adistribution that provides a command that is also provided by a different,previously installed, distribution.
Example:
"python.commands":{"installer_must_handle":true,"wrap_console":[{"chair":"chair:run_cli"}],"wrap_gui":[{"chair-gui":"chair:run_gui"}],"prebuilt":["reduniforms"]}
python.constraints extensionThepython.constraints extension contains two custom subfields:
environments: supported installation environmentsextension_metadata: required exact matches in extension metadatafields published by other installed componentsBuild tools SHOULD mark this extension as requiring handling by installers.
Index servers SHOULD allow distributions to be uploaded with constraintsthat cannot be satisfied using that index, but MAY notify distributionauthors of any such potential compatibility issues.
Installation tools SHOULD report an error if constraints are specified bythe distribution and the target installation environment fails to satisfythem, MUST at least emit a warning, and MAY allow the user toforce the installation to proceed regardless.
Example:
"python.constraints":{"installer_must_handle":true,"environments":["python_version >= 2.6"],"extension_metadata":{"fortranlib":{"fortranlib.compatibility":{"fortran_abi":"openblas-g77"}}}}
Theenvironments subfield is a list of strings specifying theenvironments that the distribution explicitly supports. An environment isconsidered supported if it matches at least one of the environment markersgiven.
If this field is not given in the metadata, it is assumed that thedistribution supports any platform supported by Python.
Individual entries are environment markers, as described inPEP 426.
The two main uses of this field are to declare which versions of Pythonand which underlying operating systems are supported.
Examples indicating supported Python versions:
# Supports Python 2.6+"environments":["python_version >= '2.6'"]# Supports Python 2.6+ (for 2.x) or 3.3+ (for 3.x)"environments":["python_version >= '3.3'","'3.0' > python_version >= '2.6'"]
Examples indicating supported operating systems:
# Windows only"environments":["sys_platform == 'win32'"]# Anything except Windows"environments":["sys_platform != 'win32'"]# Linux or BSD only"environments":["'linux' in sys_platform","'bsd' in sys_platform"]
Example where the supported Python version varies by platform:
# The standard library's os module has long supported atomic renaming# on POSIX systems, but only gained atomic renaming on Windows in Python# 3.3. A distribution that needs atomic renaming support for reliable# operation might declare the following supported environments."environment":["python_version >= '2.6' and sys_platform != 'win32'","python_version >= '3.3' and sys_platform == 'win32'"]
Theextension_metadata subfield is a mapping from distribution namesto extension metadata snippets that are expected to exactly match themetadata of the named distribution in the target installation environment.
Each submapping then consists of a mapping from metadata extension names tothe exact expected values of a subset of fields.
For example, a distribution calledfortranlib may publish a differentFORTRAN ABI depending on how it is built, and any related projects that areinstalled into the same runtime environment should use matching buildoptions. This can be handled by having the base distribution publish acustom extension that indicates the build option that was used to createthe binary extensions:
"extensions":{"fortranlib.compatibility":{"fortran_abi":"openblas-g77"}}
Other distributions that contain binary extensions that need to be compatiblewith the base distribution would then define a suitable constraint in theirown metadata:
"python.constraints":{"installer_must_handle":true,"extension_metadata":{"fortranlib":{"fortranlib.compatibility":{"fortran_abi":"openblas-g77"}}}}
This constraint specifies that:
fortranlib must be installed (this should also be expressed as anormal dependency so that installers ensure it is satisfied)fortranlib must include the customfortranlib.compatibility extension in its published metadatafortan_abi subfield of that extension must have theexactvalueopenblas-g77.If all of these conditions are met (the distribution is installed, thespecified extension is included in the metadata, the specified subfieldshave the exact specified value), then the constraint is considered to besatisfied.
Note
The primary intended use case here is allowing C extensions with additionalABI compatibility requirements to declare those in a way that anyinstallation tool can enforce without needing to understand the details.In particular, many NumPy based scientific libraries need to be builtusing a consistent set of FORTRAN libraries, hence the “fortranlib”example.
This is the reason there’s no support for pattern matching or booleanlogic: even the “simple” version of this extension is relativelycomplex, and there’s currently no compelling rationale for making itmore complicated than it already is.
This document has been placed in the public domain.
Source:https://github.com/python/peps/blob/main/peps/pep-0459.rst
Last modified:2025-02-01 08:59:27 GMT