Permalink
Cannot retrieve contributors at this time
162 lines (119 sloc)
5.35 KB
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| PEP: 496 | |
| Title: Environment Markers | |
| Version: $Revision$ | |
| Last-Modified: $Date$ | |
| Author: James Polley <jp@jamezpolley.com> | |
| BDFL-Delegate: Nick Coghlan <ncoghlan@gmail.com> | |
| Status: Rejected | |
| Type: Informational | |
| Content-Type: text/x-rst | |
| Created: 03-Jul-2015 | |
| PEP Status | |
| ========== | |
| After this PEP was initially drafted, :pep:`508` was developed and submitted to | |
| fully specify the dependency declaration syntax, including environment markers. | |
| As a result, this PEP ended up being rejected in favour of the more comprehensive | |
| :pep:`508`. | |
| Abstract | |
| ======== | |
| An **environment marker** describes a condition about the current execution | |
| environment. They are used to indicate when certain dependencies are only | |
| required in particular environments, and to indicate supported platforms | |
| for distributions with additional constraints beyond the availability of a | |
| Python runtime. | |
| Environment markers were first specified in :pep:`345`. :pep:`426` | |
| (which would replace :pep:`345`) proposed extensions to the markers. | |
| When 2.7.10 was released, even these extensions became insufficient due to | |
| their reliance on simple lexical comparisons, and thus this PEP has been born. | |
| Rationale | |
| ========= | |
| Many Python packages are written with portability in mind. | |
| For many packages this means they aim to support a wide range of | |
| Python releases. If they depend on libraries such as ``argparse`` - | |
| which started as external libraries, but later got incorporated into | |
| core - specifying a single set of requirements is difficult, as the | |
| set of required packages differs depending on the version of Python in | |
| use. | |
| For other packages, designing for portability means supporting | |
| multiple operating systems. However, the significant differences | |
| between them may mean that particular dependencies are only needed on | |
| particular platforms (relying on ``pywin32`` only on Windows, for | |
| example)" | |
| Environment Markers attempt to provide more flexibility in a list of | |
| requirements by allowing the developer to list requirements that are | |
| specific to a particular environment. | |
| Examples | |
| ======== | |
| Here are some examples of such markers inside a requirements.txt:: | |
| pywin32 >=1.0 ; sys_platform == 'win32' | |
| unittest2 >=2.0,<3.0 ; python_version == '2.4' or python_version == '2.5' | |
| backports.ssl_match_hostname >= 3.4 ; python_version < '2.7.9' or (python_version >= '3.0' and python_version < '3.4') | |
| And here's an example of some conditional metadata included in | |
| setup.py for a distribution that requires PyWin32 both at runtime and | |
| buildtime when using Windows:: | |
| setup( | |
| install_requires=["pywin32 > 1.0 : sys.platform == 'win32'"], | |
| setup_requires=["pywin32 > 1.0 : sys.platform == 'win32'"] | |
| ) | |
| Micro-language | |
| ============== | |
| The micro-language behind this is as follows. It compares: | |
| * strings with the ``==`` and ``in`` operators (and their opposites) | |
| * version numbers with the ``<``, ``<=``, ``>=``, and ``<`` operators | |
| in addition to those supported for strings | |
| The usual boolean operators ``and`` and ``or`` can be used to combine | |
| expressions, and parentheses are supported for grouping. | |
| The pseudo-grammar is :: | |
| MARKER: EXPR [(and|or) EXPR]* | |
| EXPR: ("(" MARKER ")") | (STREXPR|VEREXPR) | |
| STREXPR: STRING [STRCMPOP STREXPR] | |
| STRCMPOP: ==|!=|in|not in | |
| VEREXPR: VERSION [VERCMPOP VEREXPR] | |
| VERCMPOP: (==|!=|<|>|<=|>=) | |
| ``SUBEXPR`` is either a Python string (such as ``'win32'``) or one of | |
| the ``Strings`` marker variables listed below. | |
| ``VEREXPR`` is a :pep:`440` version identifier, or one of the | |
| ``Version number`` marker variables listed below. Comparisons between | |
| version numbers are done using :pep:`440` semantics. | |
| Strings | |
| ------- | |
| * ``os_name``: ``os.name`` | |
| * ``sys_platform``: ``sys.platform`` | |
| * ``platform_release``: ``platform.release()`` | |
| * ``implementation_name``: ``sys.implementation.name`` | |
| * ``platform_machine``: ``platform.machine()`` | |
| * ``platform_python_implementation``: ``platform.python_implementation()`` | |
| If a particular string value is not available (such as ``sys.implementation.name`` | |
| in versions of Python prior to 3.3), the corresponding marker | |
| variable MUST be considered equivalent to the empty string. | |
| If a particular version number value is not available (such as | |
| ``sys.implementation.version`` in versions of Python prior to 3.3) the | |
| corresponding marker variable MUST be considered equivalent to ``0`` | |
| Version numbers | |
| --------------- | |
| * ``python_version``: ``platform.python_version()[:3]`` | |
| * ``python_full_version``: see definition below | |
| * ``platform_version``: ``platform.version()`` | |
| * ``implementation_version``: see definition below | |
| The ``python_full_version`` and ``implementation_version`` marker variables | |
| are derived from ``sys.version_info`` and ``sys.implementation.version`` | |
| respectively, in accordance with the following algorithm:: | |
| def format_full_version(info): | |
| version = '{0.major}.{0.minor}.{0.micro}'.format(info) | |
| kind = info.releaselevel | |
| if kind != 'final': | |
| version += kind[0] + str(info.serial) | |
| return version | |
| python_full_version = format_full_version(sys.version_info) | |
| implementation_version = format_full_version(sys.implementation.version) | |
| ``python_full_version`` will typically correspond to ``sys.version.split()[0]``. | |
| Copyright | |
| ========= | |
| This document has been placed in the public domain. | |
| .. | |
| Local Variables: | |
| mode: indented-text | |
| indent-tabs-mode: nil | |
| sentence-end-double-space: t | |
| fill-column: 70 | |
| coding: utf-8 |