updated after some feedback from distutils-SIG and MAL

This commit is contained in:
Tarek Ziadé 2009-10-12 14:59:50 +00:00
parent 07c651b6d2
commit c8c5884bff
1 changed files with 90 additions and 14 deletions

View File

@ -31,7 +31,7 @@ So, basically, you download it, and run::
0.6.4 0.6.4
Where ``name`` and ``version`` are metadata fields. This is working fine but Where ``name`` and ``version`` are metadata fields. This is working fine but
as soon as the developers add more code in ``setup.py``, this feature might as soon as the developers add more code in ``setup.py``, this feature might
break or in worst cases might do unwanted things on the target system. break or in worst cases might do unwanted things on the target system.
Moreover, when an OS packager wants to get the metadata of a distribution Moreover, when an OS packager wants to get the metadata of a distribution
@ -46,7 +46,7 @@ any third party code to run.
Adding a ``metadata`` section in ``setup.cfg`` Adding a ``metadata`` section in ``setup.cfg``
============================================== ==============================================
The first thing we want to introduce is a ``[metadata]`` section, in the The first thing we want to introduce is a ``[metadata]`` section, in the
``setup.cfg`` file, that may contain any field from the Metadata:: ``setup.cfg`` file, that may contain any field from the Metadata::
[metadata] [metadata]
@ -62,6 +62,24 @@ fields. If an option that corresponds to a Metadata field is given to
``setup()``, it will override the value that was possibly present in ``setup()``, it will override the value that was possibly present in
``setup.cfg``. ``setup.cfg``.
Notice that ``setup.py`` is still used and can be required to define some
options that are not part of the Metadata fields. For instance, the
``sdist`` command can use options like ``packages`` or ``scripts``.
Multi-lines values
==================
Some Metadata fields can have multiple values. To keep ``setup.cfg`` compatible
with ``ConfigParser`` and the RFC 822 ``LONG HEADER FIELDS`` (see section 3.1.1),
these are expressed with ``,``-separated values::
requires = pywin32, bar > 1.0, foo
When this variable is read, the values are parsed and transformed into a list:
``['pywin32', 'bar > 1.0', 'foo']``.
Context-dependant sections Context-dependant sections
========================== ==========================
@ -75,8 +93,8 @@ environment. Here's some examples::
version = 0.6.4 version = 0.6.4
[metadata:sys_platform == 'win32'] [metadata:sys_platform == 'win32']
requires = pywin32 requires = pywin32, bar > 1.0
requires = bar > 1.0 obsoletes = pywin31
[metadata:os_machine == 'i386'] [metadata:os_machine == 'i386']
requires = foo requires = foo
@ -90,12 +108,12 @@ environment. Here's some examples::
Every ``[metadata:condition]`` section will be used only if the condition Every ``[metadata:condition]`` section will be used only if the condition
is met when the file is read. The background motivation for these is met when the file is read. The background motivation for these
context-dependant sections is to be able to define requirements that varies context-dependant sections is to be able to define requirements that varies
depending on the platform the distribution might be installed on. depending on the platform the distribution might be installed on.
(see PEP 314). (see PEP 314).
The micro-language behind this is the simplest possible: it compares only The micro-language behind this is the simplest possible: it compares only
strings, with the ``==`` and ``in`` operators (and their opposites), and strings, with the ``==`` and ``in`` operators (and their opposites), and
with the ability to combine expressions. It makes it also easy to understand with the ability to combine expressions. It makes it also easy to understand
to non-pythoneers. to non-pythoneers.
The pseudo-grammar is :: The pseudo-grammar is ::
@ -107,11 +125,14 @@ where ``EXPR`` belongs to any of those:
- python_version = '%s.%s' % (sys.version_info[0], sys.version_info[1]) - python_version = '%s.%s' % (sys.version_info[0], sys.version_info[1])
- os_name = os.name - os_name = os.name
- sys_platform = sys.platform - sys_platform = sys.platform
- os_version = os.uname()[3] - platform_version = platform.version()
- os_machine = os.uname()[4] - platform_machine = platform.machine()
- a free string, like ``2.4``, or ``win32`` - a free string, like ``2.4``, or ``win32``
Distutils will provide a function that is able to read the metadata Notice that ``in`` is restricted to strings, meaning that it is not possible
to use other sequences like tuples or lists on the left side.
Distutils will provide a function that is able to generate the metadata
of a distribution, given a ``setup.cfg`` file, for the execution environment:: of a distribution, given a ``setup.cfg`` file, for the execution environment::
>>> from distutils.util import local_metadata >>> from distutils.util import local_metadata
@ -121,11 +142,66 @@ of a distribution, given a ``setup.cfg`` file, for the execution environment::
This means that a vanilla Python will be able to read the metadata of a This means that a vanilla Python will be able to read the metadata of a
package without running any third party code. package without running any third party code.
Notice that this feature is not restricted to the ``metadata`` namespace.
Consequently, any other section can be extended with such context-dependant
sections.
Impact on PKG-INFO generation and PEP 314
=========================================
When ``PKG-INFO`` is generated by Distutils, every field that relies on a
condition will have that condition written at the end of the line, after a `;`
separator::
Metadata-Version: 1.2
Name: distribute
Version: 0.6.4
...
Requires: pywin32, bar > 1.0; sys_platform == 'win32'
Requires: foo; os_machine == 'i386'
Requires: bar; python_version == '2.4' or python_version == '2.5'
Requires: baz; 'linux' in sys_platform
Obsoletes = pywin31; sys_platform == 'win32'
...
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Python Software Foundation License
Notice that this file can be opened with the ``DistributionMetadata`` class.
This class will be able to use the micro-language using the execution
environment.
Let's run in on a ``Python 2.5 i386 Linux``::
>>> from distutils.dist import DistributionMetadata
>>> metadata = DistributionMetadata('PKG_INFO')
>>> metadata.get_requires()
['foo', 'bar', 'baz']
The execution environment can be overriden in case we want to get the meyadata
for another environment::
>>> env = {'python_version': '2.4',
... 'os_name': 'nt',
... 'sys_platform': 'win32',
... 'platform_version': 'MVCC++ 6.0'
... 'platform_machine': 'i386'}
...
>>> metadata = DistributionMetadata('PKG_INFO', environment=env)
>>> metadata.get_requires()
['bar > 1.0', 'foo', 'bar']
PEP 314 is changed accordingly, meaning that each field will be able to
have that extra condition marker.
Compatiblity Compatiblity
============ ============
This change is fully backward compatible since it just adds a section in the This change is is based on a new metadata ``1.2`` format meaning that
``ConfigParser``-compatible ``setup.cfg`` file. Distutils will be able to distinguish old PKG-INFO files from new ones.
The ``setup.cfg`` file change will stay ``ConfigParser``-compatible and
will not break existing ``setup.cfg`` files.
Limitations Limitations
=========== ===========
@ -134,12 +210,12 @@ We are not providing ``<`` and ``>`` operators at this time, and
``python_version`` is a regular string. This implies using ``or`` operators ``python_version`` is a regular string. This implies using ``or`` operators
when a section needs to be restricted to a couple of Python versions. when a section needs to be restricted to a couple of Python versions.
Although, if PEP 386 is accepted, ``python_version`` could be changed Although, if PEP 386 is accepted, ``python_version`` could be changed
internally into something comparable with strings, and internally into something comparable with strings, and
``<`` and ``>`` operators introduced. ``<`` and ``>`` operators introduced.
Last, if a distribution is unable to set all metadata fields in ``setup.cfg``, Last, if a distribution is unable to set all metadata fields in ``setup.cfg``,
that's fine, the fields will be set to ``UNKNOWN`` when ``local_metadata`` is that's fine, the fields will be set to ``UNKNOWN`` when ``local_metadata`` is
called. Getting ``UNKNOWN`` values will mean that it might be necessary to called. Getting ``UNKNOWN`` values will mean that it might be necessary to
run the ``setup.py`` command line interface to get the whole set of metadata. run the ``setup.py`` command line interface to get the whole set of metadata.
Acknowledgments Acknowledgments