[Distutils] New PEP : dependency specification

Robert Collins robertc at robertcollins.net
Wed Nov 11 15:38:18 EST 2015


Next iteration:

diff --git a/dependency-specification.rst b/dependency-specification.rst
index d60df6e..72a87f1 100644
--- a/dependency-specification.rst
+++ b/dependency-specification.rst
@@ -117,7 +117,8 @@ environments::
 Optional components of a distribution may be specified using the extras
 field::

-    identifier    = ( digit | letter | '-' | '_' | '.')+
+    identifier    = ( letterOrDigit |
+                      letterOrDigit (letterOrDigit | '-' | '_' |
'.')* letterOrDigit )
     name          = identifier
     extras_list   = identifier (wsp* ',' wsp* identifier)*
     extras        = '[' wsp* extras_list? ']'
@@ -146,7 +147,12 @@ Names
 Python distribution names are currently defined in PEP-345 [#pep345]_. Names
 act as the primary identifier for distributions. They are present in all
 dependency specifications, and are sufficient to be a specification on their
-own.
+own. However, PyPI places strict restrictions on names - they must match a
+case insensitive regex or they won't be accepted. Accordingly in this PEP we
+limit the acceptable values for identifiers to that regex. A full redefinition
+of name may take place in a future metadata PEP::
+
+    ^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$

 Extras
 ------
@@ -199,13 +205,18 @@ do for strings in Python. The <version_cmp>
operators use the PEP-440
 [#pep440]_ version comparison rules when those are defined (that is when both
 sides have a valid version specifier). If there is no defined PEP-440
 behaviour and the operator exists in Python, then the operator falls back to
-the Python behaviour. Otherwise the result of the operator is False.
+the Python behaviour. Otherwise an error should be raised. e.g. the following
+will result in  errors::
+
+    "dog" ~= "fred"
+    python_version ~= "surprise"

 User supplied constants are always encoded as strings with either ``'`` or
 ``"`` quote marks. Note that backslash escapes are not defined, but existing
 implementations do support them them. They are not included in this
-specification because none of the variables to which constants can be compared
-contain quote-requiring values.
+specification because they add complexity and there is no observable need for
+them today. Similarly we do not define non-ASCII character support: all the
+runtime variables we are referencing are expected to be ASCII-only.

 The variables in the marker grammar such as "os_name" resolve to values looked
 up in the Python runtime. With the exception of "extra" all values are defined
@@ -223,8 +234,8 @@ The "extra" variable is special. It is used by
wheels to signal which
 specifications apply to a given extra in the wheel ``METADATA`` file, but
 since the ``METADATA`` file is based on a draft version of PEP-426, there is
 no current specification for this. Regardless, outside of a context where this
-special handling is taking place, the "extra" variable should result in a
-SyntaxError like all other unknown variables.
+special handling is taking place, the "extra" variable should result in an
+error like all other unknown variables.

 .. list-table::
    :header-rows: 1
@@ -237,7 +248,8 @@ SyntaxError like all other unknown variables.
      - ``posix``, ``java``
    * - ``sys_platform``
      - ``sys.platform``
-     - ``linux``, ``darwin``, ``java1.8.0_51``
+     - ``linux``, ``linux2``, ``darwin``, ``java1.8.0_51`` (note that "linux"
+       is from Python3 and "linux2" from Python2)
    * - ``platform_machine``
      - ``platform.machine()``
      - ``x86_64``
@@ -268,7 +280,7 @@ SyntaxError like all other unknown variables.
      - see definition below
      - ``3.4.0``, ``3.5.0b1``
    * - ``extra``
-     - A SyntaxError except when defined by the context interpreting the
+     - An error except when defined by the context interpreting the
        specification.
      - ``test``

@@ -282,7 +294,10 @@ The ``implementation_version`` marker variable is
derived from
             version += kind[0] + str(info.serial)
         return version

-    implementation_version = format_full_version(sys.implementation.version)
+    if hasattr(sys, 'implementation'):
+        implementation_version =
format_full_version(sys.implementation.version)
+    else:
+        implementation_version = "0"

 Backwards Compatibility
 =======================
@@ -322,9 +337,9 @@ we needed a specification that included them in
their modern form. This PEP
 brings together all the currently unspecified components into a specified
 form.

-The requirement specifier EBNF is lifted from setuptools pkg_resources
-documentation, since we wish to avoid depending on a defacto, vs PEP
-specified, standard.
+The requirement specifier was adopted from the EBNF in the setuptools
+pkg_resources documentation, since we wish to avoid depending on a defacto, vs
+PEP specified, standard.

 Complete Grammar
 ================
@@ -333,14 +348,14 @@ The complete parsley grammar::

     wsp           = ' ' | '\t'
     version_cmp   = wsp* <'<' | '<=' | '!=' | '==' | '>=' | '>' | '~=' | '==='>
-    version       = wsp* <( letterOrDigit | '-' | '_' | '.' | '*' )+>
+    version       = wsp* <( letterOrDigit | '-' | '_' | '.' | '*' |
'+' | '!' )+>
     version_one   = version_cmp:op version:v -> (op, v)
     version_many  = version_one:v1 (wsp* ',' version_one)*:v2 -> [v1] + v2
     versionspec   = ('(' version_many:v ')' ->v) | version_many
     urlspec       = '@' wsp* <URI_reference>
     marker_op     = version_cmp | 'in' | 'not in'
     python_str_c  = (wsp | letter | digit | '(' | ')' | '.' | '{' | '}' |
-                     '-' | '_' | '*')
+                     '-' | '_' | '*' | '#')
     dquote        = '"'
     squote        = '\\''
     python_str    = (squote <(python_str_c | dquote)*>:s squote |
@@ -359,7 +374,8 @@ The complete parsley grammar::
     marker        = (wsp* marker_expr:m ( wsp* ("and" | "or"):o wsp*
                      marker_expr:r -> (o, r))*:ms -> (m, ms))
     quoted_marker = ';' wsp* marker
-    identifier    = <( digit | letter | '-' | '_' | '.')+>
+    identifier    = <( letterOrDigit |
+                      letterOrDigit (letterOrDigit | '-' | '_' |
'.')* letterOrDigit )>
     name          = identifier
     extras_list   = identifier:i (wsp* ',' wsp* identifier)*:ids -> [i] + ids
     extras        = '[' wsp* extras_list?:e ']' -> e

On 11 November 2015 at 19:41, Nick Coghlan <ncoghlan at gmail.com> wrote:
> On 11 November 2015 at 16:11, Robert Collins <robertc at robertcollins.net> wrote:
>>  - fixed a bug in the marker language that happened somewhere in
>> PEP-426. In PEP 345 markers were strictly 'LHS OP RHS' followed by AND
>> or OR and then another marker expression. The grammar in PEP-426
>> however allowed things like "(python_version) and
>> (python_version=='2.7')" which I believe wasn't actually the intent -
>> truthy values are not defined there. So the new grammar does not allow
>> ("fred" and "bar") or other such things - and and or are exclusively
>> between well defined expressions now.
>
> Right, Vinay pointed out that the use of parentheses for grouping
> wasn't well defined in 345, but instead grew implicitly out of their
> evaluation as a Python subset. I attempted to fix that in 426, but
> didn't intend to allow non-comparisons as operands for AND and OR.
>
> Cheers,
> Nick.
>
> --
> Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia



-- 
Robert Collins <rbtcollins at hp.com>
Distinguished Technologist
HP Converged Cloud


More information about the Distutils-SIG mailing list