On Tue, Sep 11, 2012 at 3:19 PM, Daniel Holth <dho...@gmail.com> wrote: > On Tue, Sep 11, 2012 at 3:11 PM, Erik Bray <erik.m.b...@gmail.com> wrote: >> On Tue, Sep 11, 2012 at 2:35 PM, Donald Stufft <donald.stu...@gmail.com> >> wrote: >>> I was digging through PEP386 & PEP345 today, and I noticed something odd >>> about the wording of PEP345. >>> >>> It states: >>> >>> When a version is provided, it always includes all versions that starts >>> with the same value. For >>> example the "2.5" version of Python will include versions like "2.5.2" >>> or "2.5.3". Pre and post >>> releases in that case are excluded. So in our example, versions like >>> "2.5a1" are not included >>> when "2.5" is used. If the first version of the range is required, it >>> has to be explicitly given. In >>> our example, it will be "2.5.0". >>> >>> It also states: >>> >>> In that case, "2.5.0" will have to be explicitly used to avoid any >>> confusion between the "2.5" >>> notation that represents the full range. It is a recommended practice to >>> use schemes of the >>> same length for a series to completely avoid this problem. >>> >>> This effectively translates to an inability to pin to an exact version. Even >>> in the case of specifying >>> == it checks that the version "starts with" the value you selected. So if >>> you pin to "2.5", and the >>> author then releases "2.5.1", that will count as ==2.5. If you try to then >>> pin to "2.5.0", and the >>> author releases "2.5.0.1", then that will count as ==2.5.0. >>> >>> Essentially this translates to: >>> >>> ==2.5 -> >=2.5<2.6 >>> ==2.5.0 -> >=2.5.0<2.5.1 >>> ==2.5.0.0 -> >=2.5.0.0<2.5.0.1 >>> >>> Which means that version specifiers are _always_ ranges and are never exact >>> versions. The PEP >>> as written relies on authors to decide beforehand how many digits they are >>> going to use in their >>> versions, and for them to never increase or decrease that number. >>> >>> I also checked to see if Distutils2/packaging implemented VersionPredicates >>> that way or if they >>> allowed specifying an exact version. It turned out that it implements the >>> PEP as written: >>> >>>>>> from distutils2 import version >>>>>> predicate = version.VersionPredicate("foo (==2.5)") >>>>>> print predicate >>> foo (==2.5) >>>>>> predicate.match("2.5") >>> True >>>>>> predicate.match("2.5.0") >>> True >>>>>> predicate.match("2.5.0.0") >>> True >>>>>> predicate.mach("2.5.0.5") >>> True >> >> That's kind of annoying. Does anyone know if this is by design? >> >> FWIW there is a workaround. For example if you want to pin to exactly 2.5.1: >> >>>>> predicate = version.VersionPredicate("foo (==2.5.1,<2.5.1.1)") >>>>> predicate.match('2.5.1') >> True >>>>> predicate.match('2.5.2') >> False >>>>> predicate.match('2.5.1.0') >> True >>>>> predicate.match('2.5.1.1') > > But you could still release 2.5.1.0.0? I suppose we limit the number > of version parts these days. > > Why don't we update the spec so that (2.0) means (2.0) the range, and > (==2.0) means 2.0 (exactly). > > Daniel
The PEP is ambiguous on this, but you could get away with reading it as "When a version is provided (without a conditional operator) it always includes all versions that start with the same value". Although it's unwritten in the PEP exactly how the operators are meant to be interpreted, I would say they should be interpreted strictly. Erik _______________________________________________ Distutils-SIG maillist - Distutils-SIG@python.org http://mail.python.org/mailman/listinfo/distutils-sig