[Distutils] PEP440: >1.7 vs >=1.7

Donald Stufft donald at stufft.io
Sun Dec 28 08:12:24 CET 2014


> On Dec 27, 2014, at 9:26 PM, Donald Stufft <donald at stufft.io> wrote:
> 
> 
>> On Dec 27, 2014, at 9:10 PM, Marcus Smith <qwcode at gmail.com <mailto:qwcode at gmail.com>> wrote:
>> 
>> In gives me a minor bit of pause. However any alternative that I can come up
>> with bothers me more, especially since I don't believe many people actually
>> even *use* a bare > and any alternative I can come up with has worse behavior
>> for operators which get much more use.
>> 
>> what about making >=,<= also use the series concept? where does that go wrong?
>> 
> 
> 
> To be clear, you’re talking about doing something like:
> 
> >1.7 is >1.7 AND !=1.7.* which would correlate to >1.7 OR ==1.7.*?
> 
> Honestly, the thing that I dislike about that is it takes a behavior which is
> less intuitive (I do agree that the behavior of > is less intuitive) and
> applies to globally. I don't think people would expect >=1.7 to match 1.7.dev0
> and given that I don't think people would expect >=1.7.0 to _not_match
> 1.7.dev0.
> 
> I totally agree that the behavior of > isn't the greatest, I don't think the
> solution to that problem is to globally apply that particular wart. The only
> *reasonable* solutions I can think of are:
> 
> 1. Make < and > both act as simple comparison operators, and have >1.7 and
>    >1.7.0 both allow 1.7.1. This would include also allowing 1.7.dev0 to be
>    <1.7 and <1.7.0.
> 
> 2. Make < and > both act as "exclusive comparison operators", and which is
>    the current behavior.
> 
> 3. Make < and > both act as simple comparison operators, but include a special
>    case that < does not ever match pre-releases of the version mentioned in
>    the specifier. So <3 would not match a pre-released like 3.dev0, and <3.1
>    would not match a pre-release like 3.1.dev0 but would match a pre-release
>    like 3.0.dev0.
> 
> It may be that the correct solution is to just treat pre-releases as special
> and just switch to 3.
> 

After thinking about this some more, I made a PR that adjusts the packaging
library so that is has semantics which might be better overall than what is
currently in PEP 440. This PR is at https://github.com/pypa/packaging/pull/25
if someone wants to play with it at all, but the highlights are:

* 1.7.1 matches >1.7 (previously it did not)
* 1.7.post1 does not match >1.7 (previously it did not)
* 1.7.post1 matches >1.7.post0 (previously it did)
* 3.dev0 does not match <3.0 (previously it did)
* 3.0.dev0 does not match <3.0 (previously it did not)
* 3.0.dev0 matches <3.0rc1 (previously it did)

Instead of having >V and <V impliy !=V.*, this means that:

1. A <V does not match a pre-release of V unless V is itself a pre-release.
2. A >V does not match a post-release of V unless V is itself a post-release.
3. A >V does not match a V+local.version.

Implicitly these three rules are also true, but they are true because of the
ordered nature of the versions and the mathemtical meaning of > and < rather
than any rule mentioned in the PEP:

4. A <V does not match a post-release of V unless V is itself a post-release.
5. A >V does not match a pre-release of V unless V is itself a pre-release.
6. A <V does not match a V+local.version.

If you check out my branch, you can play around with the specifier rules as
I've implemented them now by just doing:

    >>> from packaging.specifiers import SpecifierSet
    >>> SpecifierSet(">1.7").contains("1.7.1", prereleases=True)
    True
    >>> SpecifierSet(">1.7").contains("1.7.post1", prereleases=True)
    False
    >>> SpecifierSet(">1.7.post0").contains("1.7.post1", prereleases=True)
    True
    >>> SpecifierSet(">1.7").contains("1.7+thing.1", prereleases=True)
    False
    >>> SpecifierSet("<3.0.0").contains("3.0.dev0", prereleases=True)
    False
    >>> SpecifierSet("<3").contains("3.0.dev0", prereleases=True)
    False
    >>> SpecifierSet("<3rc1").contains("3.0.dev0", prereleases=True)
    True

Does this better match your expectations? I think I might like these rules
better as they handle zero padding similarly to ==, !=, >=, and <= (sans when
== and != have a .*) which means that a rule like <3.0 won't accept 3.dev0
even though the current PEP means that it does. I think it also follows along
better with what people expect both for > and for <.

---
Donald Stufft
PGP: 7C6B 7C5D 5E2B 6356 A926 F04F 6E3C BCE9 3372 DCFA

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/distutils-sig/attachments/20141228/b840cdbf/attachment-0001.html>


More information about the Distutils-SIG mailing list