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') Erik _______________________________________________ Distutils-SIG maillist - Distutils-SIG@python.org http://mail.python.org/mailman/listinfo/distutils-sig