First draft of entry points for metadata 2.0
This commit is contained in:
parent
fa09420ca3
commit
311a487701
239
pep-0426.txt
239
pep-0426.txt
|
@ -86,6 +86,24 @@ identification scheme.
|
|||
"rationale" section at the end of the document, as it would otherwise be
|
||||
an irrelevant distraction for future readers.
|
||||
|
||||
|
||||
A Note on Time Frames
|
||||
=====================
|
||||
|
||||
There's a lot of work going on in the Python packaging space at the moment.
|
||||
In the near term (up until the release of Python 3.4), those efforts will be
|
||||
focused on the existing metadata standards, both those defined in Python
|
||||
Enhancement Proposals, and the de facto standards defined by the setuptools
|
||||
project.
|
||||
|
||||
This PEP is about setting out a longer term goal for the ecosystem that
|
||||
captures those existing capabilities in a format that is easier to work
|
||||
with. There are still a number of key open questions (mostly related to
|
||||
source based distribution), and those won't be able to receive proper
|
||||
attention from the development community until the other near term
|
||||
concerns have been resolved.
|
||||
|
||||
|
||||
Purpose
|
||||
=======
|
||||
|
||||
|
@ -223,12 +241,16 @@ or consumes distribution version and dependency metadata.
|
|||
along with the supporting metadata file formats defined by the
|
||||
``setuptools`` project.
|
||||
|
||||
"Entry points" are a scheme for identifying Python callables or other
|
||||
objects as strings consisting of a Python module name and a module
|
||||
attribute name, separated by a colon. For example: ``"test.regrtest:main"``.
|
||||
"Distro" is used as the preferred term for Linux distributions, to help
|
||||
avoid confusion with the Python-specific meaning of the term "distribution".
|
||||
|
||||
"Distros" is used as the preferred term for Linux distributions, to help
|
||||
avoid confusion with the Python-specific meaning of the term.
|
||||
"Dist" is the preferred abbreviation for "distributions" in the sense defined
|
||||
in this PEP.
|
||||
|
||||
"Qualified name" comes from PEP 3155, and refers to the dotted name of an
|
||||
object relative to its containing module. This is useful for referring
|
||||
to method definitions on classes, as well as any other attributes of
|
||||
top level module objects.
|
||||
|
||||
|
||||
Integration and deployment of distributions
|
||||
|
@ -255,7 +277,10 @@ Integration and deployment can in turn be broken down into further substeps.
|
|||
These three steps may all occur directly on the target system. Alternatively
|
||||
the build step may be separated out by using binary archives provided by the
|
||||
publisher of the distribution, or by creating the binary archives on a
|
||||
separate system prior to deployment.
|
||||
separate system prior to deployment. The advantage of the latter approach
|
||||
is that it minimizes the dependencies that need to be installed on
|
||||
deployment targets (as the build dependencies will be needed only on the
|
||||
build systems).
|
||||
|
||||
The published metadata for distributions SHOULD allow integrators, with the
|
||||
aid of build and integration tools, to:
|
||||
|
@ -299,6 +324,25 @@ and publishers, with the aid of build and publication tools, to:
|
|||
Standard build system
|
||||
---------------------
|
||||
|
||||
.. note::
|
||||
|
||||
The standard build system currently described in the PEP is a draft based
|
||||
on existing practices for projects using distutils or setuptools as their
|
||||
build system (or other projects, like ``d2to1``, that expose a setup.py
|
||||
file for backwards compatibility with existing tools)
|
||||
|
||||
The specification doesn't currently cover expected argument support for
|
||||
the commands, which is a limitation that needs to be addressed before the
|
||||
PEP can be considered ready for acceptance.
|
||||
|
||||
It is also possible that the "meta build system" will be separated out
|
||||
into a distinct PEP in the coming months (similar to the separation of
|
||||
the versioning and requirement specification standard out to PEP 440).
|
||||
|
||||
If a `suitable API can be worked out <Metabuild system>`__, then it may
|
||||
even be possible to switch to a more declarative API for build system
|
||||
specification.
|
||||
|
||||
Both development and integration of distributions relies on the ability to
|
||||
build extension modules and perform other operations in a distribution
|
||||
independent manner.
|
||||
|
@ -318,10 +362,6 @@ development and integration activities:
|
|||
* ``python setup.py bdist_wheel``: create a binary archive from an sdist,
|
||||
source archive or VCS checkout
|
||||
|
||||
Future iterations of the metadata and associated PEPs may aim to replace
|
||||
these ``distutils``/``setuptools`` dependent commands with build system
|
||||
independent entry points.
|
||||
|
||||
|
||||
Metadata format
|
||||
===============
|
||||
|
@ -436,6 +476,48 @@ When serialised to a file, the name used for this metadata set SHOULD
|
|||
be ``pydist-dependencies.json``.
|
||||
|
||||
|
||||
Export metadata
|
||||
---------------
|
||||
|
||||
Distributions may define components that are intended for use by other
|
||||
distributions (such as plugins). As it can be beneficial to know whether or
|
||||
not a distribution defines any such exports without needing to parse any
|
||||
metadata, a suitable subset is defined for serialisation to a separate file
|
||||
in the ``dist-info`` metadata directory.
|
||||
|
||||
The external command metadata consists of the following fields:
|
||||
|
||||
* ``metadata_version``
|
||||
* ``generator``
|
||||
* ``name``
|
||||
* ``version``
|
||||
* ``exports``
|
||||
|
||||
When serialised to a file, the name used for this metadata set SHOULD
|
||||
be ``pydist-exports.json``.
|
||||
|
||||
|
||||
Command metadata
|
||||
----------------
|
||||
|
||||
Distributions may define commands that will be available from the command
|
||||
line following installation. As it can be beneficial to know whether or not
|
||||
a distribution has such commands without needing to parse any metadata,
|
||||
a suitable subset is defined for serialisation to a separate file in the
|
||||
``dist-info`` metadata directory.
|
||||
|
||||
The external command metadata consists of the following fields:
|
||||
|
||||
* ``metadata_version``
|
||||
* ``generator``
|
||||
* ``name``
|
||||
* ``version``
|
||||
* ``commands``
|
||||
|
||||
When serialised to a file, the name used for this metadata set SHOULD
|
||||
be ``pydist-commands.json``.
|
||||
|
||||
|
||||
Included documents
|
||||
------------------
|
||||
|
||||
|
@ -508,7 +590,7 @@ if any. A manually produced file would omit this field.
|
|||
|
||||
Example::
|
||||
|
||||
"generator": "setuptools (0.8)"
|
||||
"generator": "setuptools (0.9)"
|
||||
|
||||
|
||||
Name
|
||||
|
@ -1348,6 +1430,141 @@ Example where the supported Python version varies by platform::
|
|||
"supports_environments": ["python_version >= '2.6' and sys_platform != 'win32'",
|
||||
"python_version >= '3.3' and sys_platform == 'win32'"]
|
||||
|
||||
Installed interfaces
|
||||
====================
|
||||
|
||||
Most Python distributions expose packages and modules for import through
|
||||
the Python module namespace. Distributions may also expose other
|
||||
interfaces when installed.
|
||||
|
||||
Export specifiers
|
||||
-----------------
|
||||
|
||||
An export specifier is a string using one of the following formats::
|
||||
|
||||
module
|
||||
module:name
|
||||
module[requires_extra]
|
||||
module:name[requires_extra]
|
||||
|
||||
The meaning of the subfields is as follows:
|
||||
|
||||
* ``module``: the module providing the export
|
||||
* ``name``: if applicable, the qualified name of the export within the module
|
||||
* ``requires_extra``: indicates the export will only work correctly if the
|
||||
additional dependencies named in the given extra are available.
|
||||
|
||||
Note that installation of extras is not tracked directly: they are merely
|
||||
a convenient way to refer to a set of dependencies that will be checked for
|
||||
at runtime.
|
||||
|
||||
.. note::
|
||||
|
||||
I tried this as a mapping with subfields, and it made the examples below
|
||||
unreadable. While this PEP is mostly for tool use, readability still
|
||||
matters to some degree for debugging purposes, and because I expect
|
||||
snippets of the format to be reused elsewhere.
|
||||
|
||||
|
||||
Modules
|
||||
-------
|
||||
|
||||
A list of module names that the distribution provides for import.
|
||||
|
||||
For names that contain dots, the portion of the name before the final dot
|
||||
MUST appear either in the installed module list or in the namespace package
|
||||
list.
|
||||
|
||||
Note that attempting to import some declared modules may result in an
|
||||
exception 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 distribution
|
||||
to declare when a particular module requires a particular extra in order
|
||||
to run correctly. On the other hand, there's an argument to be made that
|
||||
that is the point where it starts to become worthwhile to split out a
|
||||
separate distribution rather than using extras.
|
||||
|
||||
|
||||
Namespaces
|
||||
----------
|
||||
|
||||
A list of namespace packages that the distribution contributes modules to.
|
||||
|
||||
On versions of Python prior to Python 3.3 (which provides native namespace
|
||||
package support), installation tools SHOULD emit a suitable ``__init__.py``
|
||||
file to properly initialise the namespace rather than using a distribution
|
||||
provided file.
|
||||
|
||||
Installation tools SHOULD emit a warning and MAY emit an error if a
|
||||
distribution declares a namespace package that conflicts the name of an
|
||||
already installed module or vice-versa.
|
||||
|
||||
Example::
|
||||
|
||||
"namespaces": ["python_sketches"]
|
||||
|
||||
|
||||
Commands
|
||||
--------
|
||||
|
||||
The ``commands`` mapping contains three subfields:
|
||||
|
||||
* ``wrap_console``: console wrapper scripts to be generated by the installer
|
||||
* ``wrap_gui``: GUI wrapper scripts to be generated by the installer
|
||||
* ``prebuilt``: scripts created by the distribution's build process and
|
||||
installed directly to the configured scripts directory
|
||||
|
||||
``wrap_console`` and ``wrap_gui`` are both mappings of relatively arbitrary
|
||||
script names to export specifiers. The script names must follow the rules
|
||||
for distribution names. The export specifiers must refer to
|
||||
either a package with a __main__ submodule (if no ``name`` subfield is
|
||||
given in the export specifier) or else to a callable inside the named
|
||||
module.
|
||||
|
||||
Installation tools should generate appropriate wrappers as part of the
|
||||
installation process.
|
||||
|
||||
.. note::
|
||||
|
||||
Still needs more detail on what "appropriate wrapper" means.
|
||||
|
||||
``prebuilt`` is a list of script paths, relative to the scripts directory in
|
||||
a wheel file or following installation. They are provided for informational
|
||||
purpose only - installing them is handled through the normal processes for
|
||||
files created when building a distribution.
|
||||
|
||||
|
||||
Example::
|
||||
|
||||
"commands": {
|
||||
"wrap_console": [{"wrapwithpython": "chair.run_cli"}],
|
||||
"wrap_gui": [{"wrapwithpythonw": "chair:run_gui"}],
|
||||
"prebuilt": ["notawrapper"]
|
||||
}
|
||||
|
||||
|
||||
|
||||
Exports
|
||||
-------
|
||||
|
||||
The ``exports`` mapping contains relatively arbitrary subfields, each
|
||||
defining an export group. Each export group is then a mapping of relatively
|
||||
arbitrary subfields to export specifiers.
|
||||
|
||||
Both export group names and export names must follow the rules for
|
||||
distribution identifiers. It is suggested that export groups be named
|
||||
after distributions to help avoid name conflicts.
|
||||
|
||||
The meaning of exports within an export group is up to those defining the
|
||||
export group. One common use case is to advertise plugins for use by other
|
||||
software.
|
||||
|
||||
|
||||
Install hooks
|
||||
=============
|
||||
|
|
|
@ -136,6 +136,32 @@
|
|||
"$ref": "#/definitions/provides_declaration"
|
||||
}
|
||||
},
|
||||
"modules": {
|
||||
"description": "A list of modules and/or packages available for import after installing this distribution.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"$ref": "#/definitions/dotted_name"
|
||||
}
|
||||
},
|
||||
"namespaces": {
|
||||
"description": "A list of namespace packages this distribution contributes to",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"$ref": "#/definitions/dotted_name"
|
||||
}
|
||||
},
|
||||
"commands": {
|
||||
"description": "Command line interfaces provided by this distribution",
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/commands"
|
||||
},
|
||||
"exports": {
|
||||
"description": "Other exported interfaces provided by this distribution",
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/exports"
|
||||
},
|
||||
"obsoleted_by": {
|
||||
"description": "A string that indicates that this project is no longer being developed. The named project provides a substitute or replacement.",
|
||||
"type": "string",
|
||||
|
@ -155,11 +181,11 @@
|
|||
"properties": {
|
||||
"postinstall": {
|
||||
"type": "string",
|
||||
"$ref": "#/definitions/entry_point"
|
||||
"$ref": "#/definitions/export_specifier"
|
||||
},
|
||||
"preuninstall": {
|
||||
"type": "string",
|
||||
"$ref": "#/definitions/entry_point"
|
||||
"$ref": "#/definitions/export_specifier"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -221,6 +247,45 @@
|
|||
"required": ["requires"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"commands": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"wrap_console": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/export_map"
|
||||
},
|
||||
"wrap_gui": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/export_map"
|
||||
},
|
||||
"prebuilt": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"$ref": "#/definitions/relative_path"
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"exports": {
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^[0-9A-Za-z]([0-9A-Za-z_.-]*[0-9A-Za-z])?$": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/export_map"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"export_map": {
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^[0-9A-Za-z]([0-9A-Za-z_.-]*[0-9A-Za-z])?$": {
|
||||
"type": "string",
|
||||
"$ref": "#/definitions/export_specifier"
|
||||
}
|
||||
},
|
||||
"valid_name": {
|
||||
"type": "string",
|
||||
"pattern": "^[0-9A-Za-z]([0-9A-Za-z_.-]*[0-9A-Za-z])?$"
|
||||
|
@ -234,14 +299,21 @@
|
|||
"environment_marker": {
|
||||
"type": "string"
|
||||
},
|
||||
"entry_point": {
|
||||
"type": "string"
|
||||
},
|
||||
"document_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"extra_name" : {
|
||||
"type": "string"
|
||||
},
|
||||
"relative_path" : {
|
||||
"type": "string"
|
||||
},
|
||||
"export_specifier": {
|
||||
"type": "string",
|
||||
},
|
||||
"dotted_name" : {
|
||||
"type": "string",
|
||||
"pattern": "^[A-Za-z]([0-9A-Za-z_])*([.][A-Za-z]([0-9A-Za-z_])*)*$"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue