[Distutils] New PEP : dependency specification

Robert Collins robertc at robertcollins.net
Sun Nov 15 23:07:22 EST 2015


Final tweaks I hope...
tl;dr: fixed a non-PEG safe grammar construct in identifier; added
some missing whitespace from review. Added some corner case tests.

diff --git a/dependency-specification.rst b/dependency-specification.rst
index 72a87f1..a9953ed 100644
--- a/dependency-specification.rst
+++ b/dependency-specification.rst
@@ -86,7 +86,7 @@ URI is defined in std-66 [#std66]_::

     version_cmp   = wsp* '<' | '<=' | '!=' | '==' | '>=' | '>' | '~=' | '==='
     version       = wsp* ( letterOrDigit | '-' | '_' | '.' | '*' )+
-    version_one   = version_cmp version
+    version_one   = version_cmp version wsp*
     version_many  = version_one (wsp* ',' version_one)*
     versionspec   = ( '(' version_many ')' ) | version_many
     urlspec       = '@' wsp* <URI_reference>
@@ -94,7 +94,7 @@ URI is defined in std-66 [#std66]_::
 Environment markers allow making a specification only take effect in some
 environments::

-    marker_op     = version_cmp | 'in' | 'not in'
+    marker_op     = version_cmp | 'in' | 'not' wsp+ 'in'
     python_str_c  = (wsp | letter | digit | '(' | ')' | '.' | '{' | '}' |
                      '-' | '_' | '*')
     dquote        = '"'
@@ -117,11 +117,12 @@ environments::
 Optional components of a distribution may be specified using the extras
 field::

-    identifier    = ( letterOrDigit |
-                      letterOrDigit (letterOrDigit | '-' | '_' |
'.')* letterOrDigit )
+    identifier    = letterOrDigit (
+                    letterOrDigit |
+                    (( letterOrDigit | '-' | '_' | '.')* letterOrDigit ) )*
     name          = identifier
     extras_list   = identifier (wsp* ',' wsp* identifier)*
-    extras        = '[' wsp* extras_list? ']'
+    extras        = '[' wsp* extras_list? wsp* ']'

 Giving us a rule for name based requirements::

@@ -197,10 +198,11 @@ False, the dependency specification should be ignored.
 The marker language is a subset of Python itself, chosen for the ability to
 safely evaluate it without running arbitrary code that could become a security
 vulnerability. Markers were first standardised in PEP-345 [#pep345]_. This PEP
-fixes some issues that were observed in the described in PEP-426 [#pep426]_.
+fixes some issues that were observed in the design described in PEP-426
+[#pep426]_.

 Comparisons in marker expressions are typed by the comparison operator.  The
-<marker-op> operators that are not in <version_cmp> perform the same as they
+<marker_op> operators that are not in <version_cmp> perform the same as they
 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
@@ -213,7 +215,7 @@ will result in  errors::

 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
+implementations do support them. They are not included in this
 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.
@@ -349,11 +351,11 @@ The complete parsley grammar::
     wsp           = ' ' | '\t'
     version_cmp   = wsp* <'<' | '<=' | '!=' | '==' | '>=' | '>' | '~=' | '==='>
     version       = wsp* <( letterOrDigit | '-' | '_' | '.' | '*' |
'+' | '!' )+>
-    version_one   = version_cmp:op version:v -> (op, v)
+    version_one   = version_cmp:op version:v wsp* -> (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'
+    marker_op     = version_cmp | 'in' | 'not' wsp+ 'in'
     python_str_c  = (wsp | letter | digit | '(' | ')' | '.' | '{' | '}' |
                      '-' | '_' | '*' | '#')
     dquote        = '"'
@@ -374,11 +376,12 @@ 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    = <( letterOrDigit |
-                      letterOrDigit (letterOrDigit | '-' | '_' |
'.')* letterOrDigit )>
+    identifier    = <letterOrDigit (
+                    letterOrDigit |
+                    (( letterOrDigit | '-' | '_' | '.')* letterOrDigit ) )*>
     name          = identifier
     extras_list   = identifier:i (wsp* ',' wsp* identifier)*:ids -> [i] + ids
-    extras        = '[' wsp* extras_list?:e ']' -> e
+    extras        = '[' wsp* extras_list?:e wsp* ']' -> e
     name_req      = (name:n wsp* extras?:e wsp* versionspec?:v wsp*
quoted_marker?:m
                      -> (n, e or [], v or [], m))
     url_req       = (name:n wsp* extras?:e wsp* urlspec:v wsp+ quoted_marker?:m
@@ -459,10 +462,12 @@ A test program - if the grammar is in a string
``grammar``::
         wsp ...
         """
     tests = [
-        "name [fred,bar] @ http://foo.com ; python_version=='2.7'",
+        "A",
+        "aa",
         "name",
         "name>=3",
         "name>=3,<2",
+        "name [fred,bar] @ http://foo.com ; python_version=='2.7'",
         "name[quux, strange];python_version<'2.7' and platform_version=='2'",
         "name; os_name=='dud' and (os_name=='odd' or os_name=='fred')",
         "name; os_name=='dud' and os_name=='odd' or os_name=='fred'",


More information about the Distutils-SIG mailing list