[Distutils] PEP440: foo-X.Y.Z does not satisfy "foo>X.Y"?

Chris Jerdonek chris.jerdonek at gmail.com
Sun Dec 28 00:38:50 CET 2014

On Sat, Dec 27, 2014 at 2:13 AM, Marcus Smith <qwcode at gmail.com> wrote:
>> > the problem with thinking of it this way is that you naturally want to
>> > extend the concept to >=, but it doesn't work.
>> > If the concept were consistent,  1.7.dev1 would satisfy  >=1.7, but it
>> > doesn't.
>> I'm pretty sure it's consistent.  For example, "1.7.2" doesn't satisfy
>> ">1.7", but it satisfies ">=1.7" (e.g. because it's "part of the
>> series").
>> I believe the inconsistency you're mentioning doesn't have anything to
>> do with the comparison operator.  It's that pre-releases like "dev1"
>> are special cases and governed by different rules. [...] are
>> implicitly excluded
> but look at this (using setuptools 8)
>>>> '1.7.dev1' in pkg_resources.Requirement.parse('foo>=1.7')
> False
>>>> '1.7.dev1' in pkg_resources.Requirement.parse('foo<=1.7')
> True

I believe the first example is a consequence of the following two
excerpts from the PEP:

(1) From the "Developmental releases" section: "Developmental releases
are ordered by their numerical component, **immediately before the
corresponding release** [my emphasis]...."

(2) And from the "Inclusive ordered comparison" section: "An inclusive
ordered comparison clause ... will match any version where the
comparison is correct based on the relative position of the candidate
version and the specified version given the consistent ordering
defined by the standard Version scheme. ... As with version matching,
the release segment is zero padded as necessary to ensure the release
segments are compared with the same length."

Since "1.7.dev1" is before its corresponding release "1.7" in the
ordering, "1.7.dev1" does not satisfy "foo>=1.7".  Similarly,
"1.7.dev1" satisfies "foo<=1.7" since "1.7.dev1" precedes "1.7" in the

In both cases (by (2) above), you are supposed to compare the
candidate version "1.7.dev1" with the specified version "1.7".


> Only the exclusive ordering section speaks of the "!= V.*" bit.
> The inclusive section just talks of zero padding and relative ordering.
> The packaging implementation that underlies all this seems to bear this out
> as well:
> inclusive:
> https://github.com/pypa/packaging/blob/master/packaging/specifiers.py#L453
> exclusive:
> https://github.com/pypa/packaging/blob/master/packaging/specifiers.py#L461

More information about the Distutils-SIG mailing list