Assorted PEP 426 updates

* Merge conditional and unconditional deps
* Don't trust public index server "Provides" metadata
* Rename pymeta to pydist (schema file name change postponed for better diff)
* Bring schema file up to date (I think - could use an audit)
This commit is contained in:
Nick Coghlan 2013-07-14 23:27:22 +10:00
parent df6c195b0c
commit a043d88945
2 changed files with 228 additions and 307 deletions

View File

@ -13,7 +13,7 @@ Content-Type: text/x-rst
Requires: 440 Requires: 440
Created: 30 Aug 2012 Created: 30 Aug 2012
Post-History: 14 Nov 2012, 5 Feb 2013, 7 Feb 2013, 9 Feb 2013, Post-History: 14 Nov 2012, 5 Feb 2013, 7 Feb 2013, 9 Feb 2013,
27 May 2013, 20 Jun 2013, 23 Jun 2013 27 May 2013, 20 Jun 2013, 23 Jun 2013, 14 Jul 2013
Replaces: 345 Replaces: 345
@ -63,13 +63,15 @@ identification scheme.
* this PEP, covering the core metadata format * this PEP, covering the core metadata format
* PEP 440, covering the versioning identification and selection scheme * PEP 440, covering the versioning identification and selection scheme
* a new PEP to define v2.0 of the sdist format * a new PEP to define v2.0 of the sdist format
* an updated wheel PEP (v1.1) to add pymeta.json * an updated wheel PEP (v1.1) to add pydist.json (and possibly convert
* an updated installation database PEP both for pymeta.json and to add the wheel metadata file from Key:Value to JSON)
a linking scheme to better support runtime selection of dependencies * an updated installation database PEP both for pydist.json (and possibly convert
the wheel metadata file from Key:Value to JSON)
* an alternative to *.pth files that avoids system global side effects
and better supports runtime selection of dependencies
* a new static config PEP to standardise metadata generation and * a new static config PEP to standardise metadata generation and
creation of sdists creation of sdists
* PEP 439, covering a bootstrapping mechanism for ``pip`` * a PEP to cover bundling ``pip`` with the CPython installers
* a distutils upgrade PEP, adding metadata v2.0 and wheel support.
It's going to take a while to work through all of these and make them It's going to take a while to work through all of these and make them
a reality. The main change from our last attempt at this is that we're a reality. The main change from our last attempt at this is that we're
@ -361,7 +363,7 @@ judgment of reasonable metadata capacity requirements.
Metadata files Metadata files
-------------- --------------
The information defined in this PEP is serialised to ``pymeta.json`` The information defined in this PEP is serialised to ``pydist.json``
files for some use cases. These are files containing UTF-8 encoded JSON files for some use cases. These are files containing UTF-8 encoded JSON
metadata. metadata.
@ -370,11 +372,11 @@ described in this PEP.
There are three standard locations for these metadata files: There are three standard locations for these metadata files:
* as a ``{distribution}-{version}.dist-info/pymeta.json`` file in an * as a ``{distribution}-{version}.dist-info/pydist.json`` file in an
``sdist`` source distribution archive ``sdist`` source distribution archive
* as a ``{distribution}-{version}.dist-info/pymeta.json`` file in a ``wheel`` * as a ``{distribution}-{version}.dist-info/pydist.json`` file in a ``wheel``
binary distribution archive binary distribution archive
* as a ``{distribution}-{version}.dist-info/pymeta.json`` file in a local * as a ``{distribution}-{version}.dist-info/pydist.json`` file in a local
Python installation database Python installation database
.. note:: .. note::
@ -422,21 +424,16 @@ fields:
* ``source_url`` * ``source_url``
* ``extras`` * ``extras``
* ``meta_requires`` * ``meta_requires``
* ``meta_may_require``
* ``run_requires`` * ``run_requires``
* ``run_may_require``
* ``test_requires`` * ``test_requires``
* ``test_may_require``
* ``build_requires`` * ``build_requires``
* ``build_may_require``
* ``dev_requires`` * ``dev_requires``
* ``dev_may_require``
* ``provides`` * ``provides``
* ``obsoleted_by`` * ``obsoleted_by``
* ``supports_environments`` * ``supports_environments``
When serialised to a file, the name used for this metadata set SHOULD When serialised to a file, the name used for this metadata set SHOULD
be ``pymeta-dependencies.json``. be ``pydist-dependencies.json``.
Included documents Included documents
@ -457,7 +454,7 @@ Metadata validation
A `jsonschema <https://pypi.python.org/pypi/jsonschema>`__ description of A `jsonschema <https://pypi.python.org/pypi/jsonschema>`__ description of
the distribution metadata is `available the distribution metadata is `available
<http://hg.python.org/peps/file/default/pep-0426/pymeta-schema.json>`__. <http://hg.python.org/peps/file/default/pep-0426/pydist-schema.json>`__.
This schema does NOT currently handle validation of some of the more complex This schema does NOT currently handle validation of some of the more complex
string fields (instead treating them as opaque strings). string fields (instead treating them as opaque strings).
@ -924,6 +921,10 @@ Distributions may declare five differents kinds of dependency:
working on this distribution (but do not fit into one of the other working on this distribution (but do not fit into one of the other
dependency categories). dependency categories).
Within each of these categories, distributions may also declare "Extras".
Extras are dependencies that may be needed for some optional functionality,
or which are otherwise complementary to the distribution.
Dependency management is heavily dependent on the version identification Dependency management is heavily dependent on the version identification
and specification scheme defined in PEP 440. and specification scheme defined in PEP 440.
@ -932,15 +933,58 @@ a distribution does not provide them, by assuming that a missing field
indicates "Not applicable for this distribution". indicates "Not applicable for this distribution".
Dependency specifications Dependency specifiers
------------------------- ---------------------
Individual dependencies are typically defined as strings containing a While many dependencies will be needed to use a distribution at all, others
distribution name (as found in the ``name`` field). The dependency name are needed only on particular platforms or only when particular optional
features of the distribution are needed. To handle this, dependency
specifiers are mappings with the following subfields:
* ``requires``: a list of `requirement specifiers
<Requirement specifiers>`__ needed to satisfy the dependency
* ``extra``: the name of a set of optional dependencies that are requested
and installed together. See `Extras (optional dependencies)`_ for details.
* ``environment``: an environment marker defining the environment that
needs these dependencies. See `Environment markers`_ for details.
``requires`` is the only required subfield. When it is the only subfield, the
dependencies are said to be *unconditional*. If ``extra`` or ``environment``
is specified, then the dependencies are *conditional*.
All three fields may be supplied, indicating that the dependencies are
needed only when the named extra is requested in a particular environment.
Automated tools MUST combine related dependency specifiers (those with
common values for ``extra`` and ``environment``) into a single specifier
listing multiple requirements when serialising metadata or
passing it to an install hook.
Despite this required normalisation, the same extra name or environment
marker MAY appear in multiple conditional dependencies. This may happen,
for example, if an extra itself only needs some of its dependencies in
specific environments. It is only the combination of extras and environment
markers that is required to be unique in a list of dependency specifiers.
Any extras referenced from a dependency specifier MUST be named in the
`Extras`_ field for this distribution. This helps avoid typographical
errors and also makes it straightforward to identify the available extras
without scanning the full set of dependencies.
Requirement specifiers
----------------------
Individual requirements are defined as strings containing a distribution
name (as found in the ``name`` field). The distribution name
may be followed by an extras specifier (enclosed in square may be followed by an extras specifier (enclosed in square
brackets) and by a version specifier or direct reference (within brackets) and by a version specifier or direct reference (within
parentheses). parentheses).
Whitespace is permitted between the distribution name and an opening
square bracket or parenthesis. Whitespace is also permitted between a
closing square bracket and an opening parenthesis.
See `Extras (optional dependencies)`_ for details on extras and PEP 440 See `Extras (optional dependencies)`_ for details on extras and PEP 440
for details on version specifiers and direct references. for details on version specifiers and direct references.
@ -949,7 +993,7 @@ Package Index`_; while these names are often the same as the module names
as accessed with ``import x``, this is not always the case (especially as accessed with ``import x``, this is not always the case (especially
for distributions that provide multiple top level modules or packages). for distributions that provide multiple top level modules or packages).
Example dependency specifications:: Example requirement specifiers::
"Flask" "Flask"
"Django" "Django"
@ -959,36 +1003,6 @@ Example dependency specifications::
"ComfyChair[warmup] (> 0.1)" "ComfyChair[warmup] (> 0.1)"
Conditional dependencies
------------------------
While many dependencies will be needed to use a distribution at all, others
are needed only on particular platforms or only when particular optional
features of the distribution are needed. To enable this, dependency fields
are marked as either unconditional (indicated by ``requires`` in the field
name) or conditional (indicated by ``may_require``) in the field name.
Unconditional dependency fields are lists of dependency specifications, with
each entry indicated a required dependency.
Conditional dependencies are lists of mappings with the following fields:
* ``dependencies``: a list of relevant dependency specifications
* ``extra``: the name of a set of optional dependencies that are requested
and installed together. See `Extras (optional dependencies)`_ for details.
* ``environment``: an environment marker defining the environment that
needs these dependencies. See `Environment markers`_ for details.
The ``dependencies`` field is required, as is at least one of ``extra`` and
``environment``. All three fields may be supplied, indicating that the
dependency is needed only when that particular set of additional
dependencies is requested in a particular environment.
Note that the same extras and environment markers MAY appear in multiple
conditional dependencies. This may happen, for example, if an extra itself
only needs some of its dependencies in specific environments.
Mapping dependencies to development and distribution activities Mapping dependencies to development and distribution activities
--------------------------------------------------------------- ---------------------------------------------------------------
@ -999,44 +1013,33 @@ should be installed for the specified activities:
* Implied runtime dependencies: * Implied runtime dependencies:
* ``meta_requires`` * ``meta_requires``
* ``meta_may_require``
* ``run_requires`` * ``run_requires``
* ``run_may_require``
* Implied build dependencies: * Implied build dependencies:
* ``build_requires`` * ``build_requires``
* ``build_may_require``
* If running the distribution's test suite as part of the build process, * If running the distribution's test suite as part of the build process,
request the ``:meta:``, ``:run:`` and ``:test:`` extras to also request the ``:meta:``, ``:run:`` and ``:test:`` extras to also
install: install:
* ``meta_requires`` * ``meta_requires``
* ``meta_may_require``
* ``run_requires`` * ``run_requires``
* ``run_may_require``
* ``test_requires`` * ``test_requires``
* ``test_may_require``
* Implied development and publication dependencies: * Implied development and publication dependencies:
* ``meta_requires`` * ``meta_requires``
* ``meta_may_require``
* ``run_requires`` * ``run_requires``
* ``run_may_require``
* ``build_requires`` * ``build_requires``
* ``build_may_require``
* ``test_requires`` * ``test_requires``
* ``test_may_require``
* ``dev_requires`` * ``dev_requires``
* ``dev_may_require``
The notation described in `Extras (optional dependencies)`_ SHOULD be used The notation described in `Extras (optional dependencies)`_ SHOULD be used
to determine exactly what gets installed for various operations. to determine exactly what gets installed for various operations.
Installation tools SHOULD report an error if dependencies cannot be found, Installation tools SHOULD report an error if dependencies cannot be
MUST at least emit a warning, and MAY allow the user to force the satisfied, MUST at least emit a warning, and MAY allow the user to force
installation to proceed regardless. the installation to proceed regardless.
See Appendix B for an overview of mapping these dependencies to an RPM See Appendix B for an overview of mapping these dependencies to an RPM
spec file. spec file.
@ -1046,8 +1049,8 @@ Extras
------ ------
A list of optional sets of dependencies that may be used to define A list of optional sets of dependencies that may be used to define
conditional dependencies in ``"may_distribute"``, ``"run_may_require"`` and conditional dependencies in dependency fields. See
similar fields. See `Extras (optional dependencies)`_ for details. `Extras (optional dependencies)`_ for details.
The names of extras MUST abide by the same restrictions as those for The names of extras MUST abide by the same restrictions as those for
distribution names. distribution names.
@ -1080,39 +1083,13 @@ archives SHOULD define appropriate constraints in their
Example:: Example::
"meta_requires": ["ComfyUpholstery (== 1.0a2)", "meta_requires":
"ComfySeatCushion (== 1.0a2)"]
Meta may require
----------------
An abbreviation of "metadistribution may require". This is a list of
subdistributions that can easily be installed and used together by
depending on this metadistribution, but are not required in all
circumstances.
Any extras referenced from this field MUST be named in the `Extras`_ field.
In this field, automated tools:
* MUST allow strict version matching
* MUST NOT allow more permissive version specifiers.
* MAY allow direct references
Public index servers SHOULD NOT allow the use of direct references in
uploaded distributions. Direct references are intended primarily as a
tool for software integrators rather than publishers.
Distributions that rely on direct references to platform specific binary
archives SHOULD defined appropriate constraints in their
``supports_environments`` field.
Example::
"meta_may_require": [
{ {
"dependencies": ["CupOfTeaAtEleven (== 1.0a2)"], "requires": ["ComfyUpholstery (== 1.0a2)",
"ComfySeatCushion (== 1.0a2)"]
},
{
"requires": ["CupOfTeaAtEleven (== 1.0a2)"],
"environment": "'linux' in sys.platform" "environment": "'linux' in sys.platform"
} }
] ]
@ -1129,31 +1106,16 @@ in ``meta_requires`` instead.
Example:: Example::
"run_requires": ["SciPy", "PasteDeploy", "zope.interface (>3.5.0)"] "run_requires":
Run may require
---------------
A list of other distributions that may be needed to actually run this
distribution, based on the extras requested and the target deployment
environment.
Any extras referenced from this field MUST be named in the `Extras`_ field.
Automated tools MUST NOT allow strict version matching clauses or direct
references in this field - if permitted at all, such clauses should appear
in ``meta_may_require`` instead.
Example::
"run_may_require": [
{ {
"dependencies": ["pywin32 (>1.0)"], "requires": ["SciPy", "PasteDeploy", "zope.interface (>3.5.0)"]
},
{
"requires": ["pywin32 (>1.0)"],
"environment": "sys.platform == 'win32'" "environment": "sys.platform == 'win32'"
}, },
{ {
"dependencies": ["SoftCushions"], "requires": ["SoftCushions"],
"extra": "warmup" "extra": "warmup"
} }
] ]
@ -1173,32 +1135,16 @@ direct references in this field.
Example:: Example::
"test_requires": ["unittest2"] "test_requires":
Test may require
----------------
A list of other distributions that may be needed in order to run the
automated tests for this distribution.
Any extras referenced from this field MUST be named in the `Extras`_ field.
Automated tools MAY disallow strict version matching clauses and direct
references in this field and SHOULD at least emit a warning for such clauses.
Public index servers SHOULD NOT allow strict version matching clauses or
direct references in this field.
Example::
"test_may_require": [
{ {
"dependencies": ["pywin32 (>1.0)"], "requires": ["unittest2"]
},
{
"requires": ["pywin32 (>1.0)"],
"environment": "sys.platform == 'win32'" "environment": "sys.platform == 'win32'"
}, },
{ {
"dependencies": ["CompressPadding"], "requires": ["CompressPadding"],
"extra": "warmup" "extra": "warmup"
} }
] ]
@ -1221,39 +1167,16 @@ direct references in this field.
Example:: Example::
"build_requires": ["setuptools (>= 0.7)"] "build_requires":
Build may require
-----------------
A list of other distributions that may be needed when this distribution
is built (creating a binary archive from an sdist, source archive or
VCS checkout), based on the features requested and the build environment.
Note that while these are build dependencies for the distribution being
built, the installation is a *deployment* scenario for the dependencies.
Any extras referenced from this field MUST be named in the `Extras`_ field.
Automated tools MAY assume that all extras are implicitly requested when
installing build dependencies.
Automated tools MAY disallow strict version matching clauses and direct
references in this field and SHOULD at least emit a warning for such clauses.
Public index servers SHOULD NOT allow strict version matching clauses or
direct references in this field.
Example::
"build_may_require": [
{ {
"dependencies": ["pywin32 (>1.0)"], "requires": ["setuptools (>= 0.7)"]
},
{
"requires": ["pywin32 (>1.0)"],
"environment": "sys.platform == 'win32'" "environment": "sys.platform == 'win32'"
}, },
{ {
"dependencies": ["cython"], "requires": ["cython"],
"extra": "c-accelerators" "extra": "c-accelerators"
} }
] ]
@ -1280,35 +1203,12 @@ direct references in this field.
Example:: Example::
"dev_requires": ["hgtools", "sphinx (>= 1.0)"] "dev_requires":
Dev may require
---------------
A list of other distributions that may be needed during development of
this distribution, based on the features requested and the build environment.
This should only be needed if the project's own utility scripts have
platform specific dependencies that aren't already defined as deployment
or build dependencies.
Any extras referenced from this field MUST be named in the `Extras`_ field.
Automated tools MAY assume that all extras are implicitly requested when
installing development dependencies.
Automated tools MAY disallow strict version matching clauses and direct
references in this field and SHOULD at least emit a warning for such clauses.
Public index servers SHOULD NOT allow strict version matching clauses or
direct references in this field.
Example::
"dev_may_require": [
{ {
"dependencies": ["pywin32 (>1.0)"], "requires": ["hgtools", "sphinx (>= 1.0)"]
},
{
"requires": ["pywin32 (>1.0)"],
"environment": "sys.platform == 'win32'" "environment": "sys.platform == 'win32'"
} }
] ]
@ -1334,11 +1234,8 @@ project is able to include a ``"provides": ["distribute"]`` entry to
satisfy any projects that require the now obsolete distribution's name. satisfy any projects that require the now obsolete distribution's name.
To avoid malicious hijacking of names, when interpreting metadata retrieved To avoid malicious hijacking of names, when interpreting metadata retrieved
from a public index server, automated tools MUST prefer the distribution from a public index server, automated tools MUST NOT pay any attention to
named in a version specifier over other distributions using that ``"provides"`` entries that do not correspond to a published distribution.
distribution's name in a ``"provides"`` entry. Index servers MAY drop such
entries from the metadata they republish, but SHOULD NOT refuse to publish
such distributions.
However, to appropriately handle project forks and mergers, automated tools However, to appropriately handle project forks and mergers, automated tools
MUST accept ``"provides"`` entries that name other distributions when the MUST accept ``"provides"`` entries that name other distributions when the
@ -1346,7 +1243,7 @@ entry is retrieved from a local installation database or when there is a
corresponding ``"obsoleted_by"`` entry in the metadata for the named corresponding ``"obsoleted_by"`` entry in the metadata for the named
distribution. distribution.
A distribution may also provide a "virtual" project name, which does A distribution may wish to depend on a "virtual" project name, which does
not correspond to any separately distributed project: such a name not correspond to any separately distributed project: such a name
might be used to indicate an abstract capability which could be supplied might be used to indicate an abstract capability which could be supplied
by one of multiple projects. For example, multiple projects might supply by one of multiple projects. For example, multiple projects might supply
@ -1354,13 +1251,20 @@ PostgreSQL bindings for use with SQL Alchemy: each project might declare
that it provides ``sqlalchemy-postgresql-bindings``, allowing other that it provides ``sqlalchemy-postgresql-bindings``, allowing other
projects to depend only on having at least one of them installed. projects to depend only on having at least one of them installed.
A version declaration may be supplied and must follow the rules described To handle this case in a way that doesn't allow for name hijacking, the
in PEP 440. The distribution's version identifier will be implied authors of the distribution that first defines the virtual dependency should
if none is specified. create a project on the public index server with the corresponding name, and
depend on the specific distribution that should be used if no other provider
is already installed. This also has the benefit of publishing the default
provider in a way that automated tools will understand.
A version declaration may be supplied as part of an entry in the provides
field and must follow the rules described in PEP 440. The distribution's
version identifier will be implied if none is specified.
Example:: Example::
"provides": ["AnotherProject (3.4)", "virtual_package"] "provides": ["AnotherProject (3.4)", "virtual-package"]
Obsoleted by Obsoleted by
@ -1596,15 +1500,15 @@ Example of a distribution with optional dependencies::
"name": "ComfyChair", "name": "ComfyChair",
"extras": ["warmup", "c-accelerators"] "extras": ["warmup", "c-accelerators"]
"run_may_require": [ "run_requires": [
{ {
"dependencies": ["SoftCushions"], "requires": ["SoftCushions"],
"extra": "warmup" "extra": "warmup"
} }
] ]
"build_may_require": [ "build_requires": [
{ {
"dependencies": ["cython"], "requires": ["cython"],
"extra": "c-accelerators" "extra": "c-accelerators"
} }
] ]
@ -1617,18 +1521,20 @@ Extra specifications MUST allow the following additional syntax:
* Multiple extras can be requested by separating them with a comma within * Multiple extras can be requested by separating them with a comma within
the brackets. the brackets.
* The following special extras request processing of the corresponding * The following special extras request processing of the corresponding
lists of dependencies: lists of dependencies:
* ``:meta:``: ``meta_requires`` and ``meta_may_require`` * ``:meta:``: ``meta_requires``
* ``:run:``: ``run_requires`` and ``run_may_require`` * ``:run:``: ``run_requires``
* ``:test:``: ``test_requires`` and ``test_may_require`` * ``:test:``: ``test_requires``
* ``:build:``: ``build_requires`` and ``build_may_require`` * ``:build:``: ``build_requires``
* ``:dev:``: ``dev_requires`` and ``dev_may_require`` * ``:dev:``: ``dev_requires``
* ``:*:``: process *all* dependency lists * ``:*:``: process *all* dependency lists
* The ``*`` character as an extra is a wild card that enables all of the * The ``*`` character as an extra is a wild card that enables all of the
entries defined in the distribution's ``extras`` field. entries defined in the distribution's ``extras`` field.
* Extras may be explicitly excluded by prefixing their name with a ``-`` * Extras may be explicitly excluded by prefixing their name with a ``-``
character (this is useful in conjunction with ``*`` to exclude only character (this is useful in conjunction with ``*`` to exclude only
particular extras that are definitely not wanted, while enabling all particular extras that are definitely not wanted, while enabling all
@ -1646,14 +1552,14 @@ allow extras to be requested explicitly.
The full set of dependency requirements is then based on the top level The full set of dependency requirements is then based on the top level
dependencies, along with those of any requested extras. dependencies, along with those of any requested extras.
Dependency examples:: Dependency examples (showing just the ``requires`` subfield)::
"run_requires": ["ComfyChair[warmup]"] "requires": ["ComfyChair[warmup]"]
-> requires ``ComfyChair`` and ``SoftCushions`` at run time -> requires ``ComfyChair`` and ``SoftCushions``
"run_requires": ["ComfyChair[*]"] "requires": ["ComfyChair[*]"]
-> requires ``ComfyChair`` and ``SoftCushions`` at run time, but -> requires ``ComfyChair`` and ``SoftCushions``, but will also
will also pick up any new extras defined in later versions pick up any new extras defined in later versions
Command line examples:: Command line examples::
@ -1670,7 +1576,8 @@ Command line examples::
-> as above, but also installs dependencies needed to run the tests -> as above, but also installs dependencies needed to run the tests
pip install ComfyChair[-,:*:,*] pip install ComfyChair[-,:*:,*]
-> installs the full set of development dependencies -> installs the full set of development dependencies, but avoids
installing ComfyChair itself
Environment markers Environment markers
@ -1693,15 +1600,15 @@ And here's an example of some conditional metadata for a distribution that
requires PyWin32 both at runtime and buildtime when using Windows:: requires PyWin32 both at runtime and buildtime when using Windows::
"name": "ComfyChair", "name": "ComfyChair",
"run_may_require": [ "run_requires": [
{ {
"dependencies": ["pywin32 (>1.0)"], "requires": ["pywin32 (>1.0)"],
"environment": "sys.platform == 'win32'" "environment": "sys.platform == 'win32'"
} }
] ]
"build_may_require": [ "build_requires": [
{ {
"dependencies": ["pywin32 (>1.0)"], "requires": ["pywin32 (>1.0)"],
"environment": "sys.platform == 'win32'" "environment": "sys.platform == 'win32'"
} }
] ]
@ -1767,9 +1674,9 @@ Updating the metadata specification
The metadata specification may be updated with clarifications without The metadata specification may be updated with clarifications without
requiring a new PEP or a change to the metadata version. requiring a new PEP or a change to the metadata version.
Adding new features (other than through the extension mechanism), or Changing the meaning of existing fields or adding new features (other than
changing the meaning of existing fields, requires a new metadata version through the extension mechanism) requires a new metadata version defined in
defined in a new PEP. a new PEP.
Appendix A: Conversion notes for legacy metadata Appendix A: Conversion notes for legacy metadata
@ -1801,28 +1708,21 @@ developers to upgrade to newer build systems.
Appendix B: Mapping dependency declarations to an RPM SPEC file Appendix B: Mapping dependency declarations to an RPM SPEC file
=============================================================== ===============================================================
As an example of mapping this PEP to Linux distro packages, assume an As an example of mapping this PEP to Linux distro packages, assume an
example project without any extras defined is split into 2 RPMs example project without any extras defined is split into 2 RPMs
in a SPEC file: ``example`` and ``example-devel``. in a SPEC file: ``example`` and ``example-devel``.
The ``meta_requires``, ``run_requires`` and applicable The ``meta_requires`` and ``run_requires`` dependencies would be mapped
``meta_may_require`` ``run_may_require`` dependencies would be mapped
to the Requires dependencies for the "example" RPM (a mapping from to the Requires dependencies for the "example" RPM (a mapping from
environment markers relevant to Linux to SPEC file conditions would environment markers relevant to Linux to SPEC file conditions would
also allow those to be handled correctly) also allow those to be handled correctly)
The ``build_requires`` and ``build_may_require`` dependencies would be The ``build_requires`` dependencies would be mapped to the BuildRequires
mapped to the BuildRequires dependencies for the "example" RPM. dependencies for the "example" RPM.
All defined dependencies relevant to Linux, including those in All defined dependencies relevant to Linux, including those in
``dev_requires``, ``test_requires``, ``dev_may_require``, and ``dev_requires`` and ``test_requires`` would become Requires dependencies
``test_may_require`` would become Requires dependencies for the for the "example-devel" RPM.
"example-devel" RPM.
If the project did define any extras, those would likely be mapped to
additional virtual RPMs with appropriate BuildRequires and Requires
entries based on the details of the dependency specifications.
A documentation toolchain dependency like Sphinx would either go in A documentation toolchain dependency like Sphinx would either go in
``build_requires`` (for example, if man pages were included in the ``build_requires`` (for example, if man pages were included in the
@ -1831,6 +1731,20 @@ documentation is published solely through ReadTheDocs or the
project website). This would be enough to allow an automated converter project website). This would be enough to allow an automated converter
to map it to an appropriate dependency in the spec file. to map it to an appropriate dependency in the spec file.
If the project did define any extras, those could be mapped to additional
virtual RPMs with appropriate BuildRequires and Requires entries based on
the details of the dependency specifications. Alternatively, they could
be mapped to other system package manager features (such as package lists
in ``yum``).
Other system package managers may have other options for dealing with
extras (Debian packagers, for example, would have the option to map them
to "Recommended" or "Suggested" package entries).
The metadata extension format should also allow distribution specific hints
to be included in the upstream project metadata without needing to manually
duplicate any of the upstream metadata in a distribution specific format.
Appendix C: Summary of differences from \PEP 345 Appendix C: Summary of differences from \PEP 345
================================================= =================================================
@ -1986,7 +1900,7 @@ Support for optional dependencies for distributions
--------------------------------------------------- ---------------------------------------------------
The new extras system allows distributions to declare optional The new extras system allows distributions to declare optional
behaviour, and to use the ``*may_require`` fields to indicate when behaviour, and to use the dependency fields to indicate when
particular dependencies are needed only to support that behaviour. It is particular dependencies are needed only to support that behaviour. It is
derived from the equivalent system that is already in widespread use as derived from the equivalent system that is already in widespread use as
part of ``setuptools`` and allows that aspect of the legacy ``setuptools`` part of ``setuptools`` and allows that aspect of the legacy ``setuptools``
@ -2011,6 +1925,10 @@ to allow a distribution to depend on tools which *do* know how to handle
the chosen extension, and the new extras mechanism, allowing support for the chosen extension, and the new extras mechanism, allowing support for
particular extensions to be provided as optional features. particular extensions to be provided as optional features.
Possible future uses for extensions include declaration of plugins for
other distributions, hints for automatic conversion to Linux system
packages, and inclusion of CVE references to mark security releases.
Support for install hooks Support for install hooks
--------------------------- ---------------------------
@ -2189,10 +2107,9 @@ MIME type registration
At some point after acceptance of the PEP, I will likely submit the At some point after acceptance of the PEP, I will likely submit the
following MIME type registration requests to IANA: following MIME type registration requests to IANA:
* Full metadata: ``application/vnd.python.pymeta+json`` * Full metadata: ``application/vnd.python.pydist+json``
* Abbreviated metadata: ``application/vnd.python.pymeta-short+json``
* Essential dependency resolution metadata: * Essential dependency resolution metadata:
``application/vnd.python.pymeta-dependencies+json`` ``application/vnd.python.pydist-dependencies+json``
It's even possible we may be able to just register the ``vnd.python`` It's even possible we may be able to just register the ``vnd.python``
namespace under the banner of the PSF rather than having to register namespace under the banner of the PSF rather than having to register
@ -2365,6 +2282,15 @@ introducing too much additional complexity for too small a gain in
expressiveness. expressiveness.
Separate lists for conditional and unconditional dependencies
-------------------------------------------------------------
Earlier versions of this PEP used separate lists for conditional and
unconditional dependencies. This turned out to be annoying to handle in
automated tools and removing it also made the PEP and metadata schema
substantially shorter, suggesting it was actually harder to explain as well.
Disallowing underscores in distribution names Disallowing underscores in distribution names
--------------------------------------------- ---------------------------------------------

View File

@ -17,7 +17,7 @@
"name": { "name": {
"description": "The name of the distribution.", "description": "The name of the distribution.",
"type": "string", "type": "string",
"pattern": "^[0-9A-Za-z]([0-9A-Za-z_.-]*[0-9A-Za-z])?$" "$ref": "#/definitions/valid_name"
}, },
"version": { "version": {
"description": "The distribution's public version identifier", "description": "The distribution's public version identifier",
@ -103,65 +103,43 @@
"$ref": "#/definitions/extra_name" "$ref": "#/definitions/extra_name"
} }
}, },
"distributes": { "meta_requires": {
"description": "A list of subdistributions made available through this metadistribution.", "description": "A list of subdistributions made available through this metadistribution.",
"type": "array", "type": "array",
"$ref": "#/definitions/dependencies" "$ref": "#/definitions/dependencies"
}, },
"may_distribute": {
"description": "A list of subdistributions that may be made available through this metadistribution, based on the extras requested and the target deployment environment.",
"$ref": "#/definitions/conditional_dependencies"
},
"run_requires": { "run_requires": {
"description": "A list of other distributions needed when to run this distribution.", "description": "A list of other distributions needed to run this distribution.",
"type": "array", "type": "array",
"$ref": "#/definitions/dependencies" "$ref": "#/definitions/dependencies"
}, },
"run_may_require": {
"description": "A list of other distributions that may be needed when this distribution is deployed, based on the extras requested and the target deployment environment.",
"$ref": "#/definitions/conditional_dependencies"
},
"test_requires": { "test_requires": {
"description": "A list of other distributions needed when this distribution is tested.", "description": "A list of other distributions needed when this distribution is tested.",
"type": "array", "type": "array",
"$ref": "#/definitions/dependencies" "$ref": "#/definitions/dependencies"
}, },
"test_may_require": {
"description": "A list of other distributions that may be needed when this distribution is tested, based on the extras requested and the target deployment environment.",
"type": "array",
"$ref": "#/definitions/conditional_dependencies"
},
"build_requires": { "build_requires": {
"description": "A list of other distributions needed when this distribution is built.", "description": "A list of other distributions needed when this distribution is built.",
"type": "array", "type": "array",
"$ref": "#/definitions/dependencies" "$ref": "#/definitions/dependencies"
}, },
"build_may_require": {
"description": "A list of other distributions that may be needed when this distribution is built, based on the extras requested and the target deployment environment.",
"type": "array",
"$ref": "#/definitions/conditional_dependencies"
},
"dev_requires": { "dev_requires": {
"description": "A list of other distributions needed when this distribution is developed.", "description": "A list of other distributions needed when this distribution is developed.",
"type": "array", "type": "array",
"$ref": "#/definitions/dependencies" "$ref": "#/definitions/dependencies"
}, },
"dev_may_require": {
"description": "A list of other distributions that may be needed when this distribution is developed, based on the extras requested and the target deployment environment.",
"type": "array",
"$ref": "#/definitions/conditional_dependencies"
},
"provides": { "provides": {
"description": "A list of strings naming additional dependency requirements that are satisfied by installing this distribution. These strings must be of the form Name or Name (Version), as for the requires field.", "description": "A list of strings naming additional dependency requirements that are satisfied by installing this distribution. These strings must be of the form Name or Name (Version)",
"type": "array", "type": "array",
"items": { "items": {
"type": "string" "type": "string",
"$ref": "#/definitions/provides_declaration"
} }
}, },
"obsoleted_by": { "obsoleted_by": {
"description": "A string that indicates that this project is no longer being developed. The named project provides a substitute or replacement.", "description": "A string that indicates that this project is no longer being developed. The named project provides a substitute or replacement.",
"type": "string", "type": "string",
"$ref": "#/definitions/version_specifier" "$ref": "#/definitions/requirement"
}, },
"supports_environments": { "supports_environments": {
"description": "A list of strings specifying the environments that the distribution explicitly supports.", "description": "A list of strings specifying the environments that the distribution explicitly supports.",
@ -171,9 +149,19 @@
"$ref": "#/definitions/environment_marker" "$ref": "#/definitions/environment_marker"
} }
}, },
"metabuild_hooks": { "install_hooks": {
"description": "The metabuild_hooks field is used to define various operations that may be invoked on a distribution in a platform independent manner.", "description": "The install_hooks field is used to define various operations that may be invoked on a distribution in a platform independent manner.",
"type": "object" "type": "object",
"properties": {
"postinstall": {
"type": "string",
"$ref": "#/definitions/entry_point"
},
"preuninstall": {
"type": "string",
"$ref": "#/definitions/entry_point"
}
}
}, },
"extensions": { "extensions": {
"description": "Extensions to the metadata may be present in a mapping under the 'extensions' key.", "description": "Extensions to the metadata may be present in a mapping under the 'extensions' key.",
@ -181,7 +169,7 @@
} }
}, },
"required": ["metadata_version", "name", "version"], "required": ["metadata_version", "name", "version", "summary"],
"additionalProperties": false, "additionalProperties": false,
"definitions": { "definitions": {
@ -207,41 +195,48 @@
"dependencies": { "dependencies": {
"type": "array", "type": "array",
"items": { "items": {
"type": "string", "type": "object",
"$ref": "#/definitions/version_specifier" "$ref": "#/definitions/dependency"
} }
}, },
"conditional_dependencies": { "dependency": {
"type": "array",
"items": {
"type": "object", "type": "object",
"properties": { "properties": {
"extra": { "extra": {
"type": "string", "type": "string",
"$ref": "#/definitions/extra_name" "$ref": "#/definitions/valid_name"
}, },
"environment": { "environment": {
"type": "string", "type": "string",
"$ref": "#/definitions/environment_marker" "$ref": "#/definitions/environment_marker"
}, },
"dependencies": { "requires": {
"type": "array", "type": "array",
"$ref": "#/definitions/dependencies" "items": {
"type": "string",
"$ref": "#/definitions/requirement"
}
} }
}, },
"required": ["dependencies"], "required": ["requires"],
"additionalProperties": false "additionalProperties": false
}
}, },
"version_specifier": { "valid_name": {
"type": "string",
"pattern": "^[0-9A-Za-z]([0-9A-Za-z_.-]*[0-9A-Za-z])?$"
},
"requirement": {
"type": "string" "type": "string"
}, },
"extra_name": { "provides_declaration": {
"type": "string" "type": "string"
}, },
"environment_marker": { "environment_marker": {
"type": "string" "type": "string"
}, },
"entry_point": {
"type": "string"
},
"document_name": { "document_name": {
"type": "string" "type": "string"
} }