On Tue, Feb 26, 2013 at 11:06 AM, Donald Stufft <donald.stu...@gmail.com> wrote: > !=1.3 allowing 1.3.1 makes sense to me. 1.3 is equivalent to 1.3.0, 1.3.1 != > 1.3.0.
Nope, the PEP explicitly disclaims the historical equivalence between 1.3 and 1.3.0. It has to, because they're very different when it comes to what the PEP now calls a "compatible release clause" (http://www.python.org/dev/peps/pep-0426/#compatible-release), Ruby gems call a "pessimistic version constraint" (http://docs.rubygems.org/read/chapter/16#page74), PHP composer calls "next significant release" (http://getcomposer.org/doc/01-basic-usage.md#package-versions) and Node.js npm calls "Tilde version range" (https://npmjs.org/doc/json.html) (Note: I also checked CPAN version ordering to see if it had an equivalent operation, but Perl's approach appears to be closer to the way pkg_resources handles ordering: http://search.cpan.org/~jpeacock/version-0.9901/lib/version.pod#How_to_compare_version_objects) However, while numeric maintenance releases are part of the problem here, the real issue is correctly handling *post* releases. Does "== 1.3" allow "1.3.post1"? Does "!= 1.3" allow "1.3.post1"? Both? Neither? If you use strict string matching for == and !=, then "!= 1.3" will allow "1.3.post1", which is utterly insane given the PEP's recommended usage of post releases solely for non-functional changes like tweaking the release notes or project metadata. Leaving == as strict and making != prefix based breaks the fundamental relationship between equality and inequality checks, so that's also not a reasonable option. That leaves making both == and != prefix based as the most reasonable alternative, as "!= 1.3" will then correctly reject "1.3.post1" and the appropriate logical relationship is maintained between the two operators. However, you then need a way to spell an *exact* version request (for use with tools like zc.buildout and pip freeze that are designed to snapshot an application configuration rather than for dependency publication in an index). My plan for that use case is to allow "is" as a comparison operator that means exactly what it says: the version required is precisely the specified version, with no prefix matching or release compatibility assessments allowed. That gives a natural progression in dependency constraints from more permissive to less permissive: Compatible version: some-dist (X.Y) # roughly equivalent to (>= X.Y, < X+1.dev0) Version equality: some-dist (== X.Y) # roughly equivalent to (>= X.Y, < X.Y+1.dev0) Version identity: some-dist (is X.Y) # must be exactly X.Y All three clauses also have clearly defined use cases: 1. Use compatible version clauses in published metadata for stable dependencies with a good backwards compatibility policy 2. Use version equality clauses in published metadata for dependencies without a good backwards compatibility policy 3. Use version identity clauses for application and deployment dependency snapshots Cheers, Nick. -- Nick Coghlan | ncogh...@gmail.com | Brisbane, Australia _______________________________________________ Distutils-SIG maillist - Distutils-SIG@python.org http://mail.python.org/mailman/listinfo/distutils-sig