[Python-Dev] Proposing PEP 345 : Metadata for Python Software Packages 1.2

Lennart Regebro regebro at gmail.com
Mon Dec 28 07:39:31 CET 2009


On Mon, Dec 28, 2009 at 05:37, Terry Reedy <tjreedy at udel.edu> wrote:
> If the first x.y release were called x.y.0, (does not sys.version include
> 0?) then x.y would unambiguously mean the series.

Yeah, well, although sys.version includes the zero, nothing else does.
The first releases are called 2.5, which is ambiguous. Both Python and
Plone leaves out the zero in the version name. IMO that's a bug. But
that's now how it is.

However, there are two ways of writing versions that are completely
unambiguous and which every programmer will immediately understand:

    2.5.0
and
    2.5.*

Done.


The comma is problematic. If you want to specify 2.5 or 2.6, it would
be natural to write:

     Requires-Python: 2.5.*, 2.6.*

Which clearly has the comma meaning "or". But it would also make sense to write:

     Requires-Python: >= 2.5.2, < 3.0.0

Where it is an "and". But trying to leave commas out leaves us with
the slightly weird syntax of

     Requires-Python: >= 2.5.2 and < 3.0.0 or >= 3.1.*

And then it's the question of in what order that should be
interpreted. And what would

     Requires-Python: >= 3.1.* or >= 2.5.2 and < 3.0.0

mean? And would

     Requires-Python: >= 2.5.2 or >= 3.1.* and  < 3.0.0

Be legal an mean anything?

My conclusion: This is a place where the normal computer logic syntax
makes so sense, it's either too restrictive, or too flexible. We need
something  custom, where we can specify pairs of two versions, min and
max and have several pairs. Also, the min version can always be
included and the max version excluded. You need to write things like:
>= 2.5.2 and < 3.0.0. You never need to write <= 2.5.7, because you
can always write < 2.5.8 instead.

Now, this "starting from and then up until but not including" is
something that is quite common in Python. Namely when slicing. It
works exactly like that. [3:9] means from 3 and up until but not
including 9. Hence, a clear and unambiguous and extremely Pythonic way
of specifying a version range is: [2.5.2:3.0.0]. No <= or commas
anywhere. We can also specify a list of ranges by having semicolons
between them. The grammar ends up something like this:

versionrequirements ::= 'Requires-Python: ' specificationlist
specificationlist   ::= specification (; specification)*
specification       ::= version | "[" [version] ":" [version] "]"
version             ::= lc_number "." (lc_number | "*") "." [lc_number | "*"]

With examples being:

     Requires-Python: [2.5.2:3.0.0]; [3.1.*:]

Or on several rows:

     Requires-Python: [2.5.2:3.0.0];
                     [3.1.2:];
                     [3.2.*]


Now, if <=>== etc is deemed necessary, we could use something like this:

versionrequirements ::= 'Requires-Python: ' specificationlist
specificationlist   ::= specification (; specification)*
specification       ::= version | minimum | maximum | miniumum " " maximum
minimum             ::= ('>' | '>=') version
maximum             ::= ('<' | '<=') version
version             ::= lc_number "." (lc_number | "*") "." [lc_number | "*"]

That would mean something like the following:

     Requires-Python: >= 2.5.2 < 3.0.0; >= 3.1*

or more clearer if it's split up in lines:

     Requires-Python: >= 2.5.2 < 3.0.0;
                     >= 3.1*

The following would be illegal:

     Requires-Python: >= 2.5.2 > 3.0.0
     Requires-Python: <= 2.5.2 < 3.0.0
     Requires-Python: <= 2.5.2 < 3.0.0 > 3.1*

No commas or ands or ors anywhere. But I like the first syntax better.


More information about the Python-Dev mailing list