How to pin a package to a specific major version or lower

Then perhaps it should be rejected as an error to use .* outside of == comparisons, since likely most user using it will not get the results they expect (as @harupy did above, and I did in my own testing)?

Well, it depends what one means by “equal to”. I’d expect it to have the same meaning as the == operator, in which case 2.4.2 would satisfy x == 2.*.

Furthermore, the definition of the wildcard operator in the PEP states

Prefix matching may be requested instead of strict comparison, by appending a trailing .* to the version identifier in the version matching clause. This means that additional trailing segments will be ignored when determining whether or not a version identifier matches the clause. If the specified version includes only a release segment, than trailing components (or the lack thereof) in the release segment are also ignored.

Following this definition, ignoring trailing segments after the first release segment, 2, 2.4.2 satisfies this constraint, as the comparison becomes 2 <= 2 which is of course True.

However, given that, evident from this discussion, even people quite familiar with the specs still interpret it differently, it would indeed seem prudent to simply make use of prefix matching with operators other than == and =! an explicit error. Indeed, per a strict reading of the existing PEP prefix matching is only valid for the == and =! operators, as they state, respectively:

The specified version identifier must be in the standard format described in Version scheme, but a trailing .* is permitted on public version identifiers as described below.

The allowed version identifiers and comparison semantics are the same as those of the Version matching operator, except that the sense of any match is inverted.

While the others state that only “version identifiers” are permitted, or (in the case of ===) explicitly prohibit prefix matching:

A compatible release clause consists of the compatible release operator ~= and a version identifier.

An inclusive ordered comparison clause includes a comparison operator and a version identifier

Arbitrary equality comparisons are simple string equality operations which do not take into account any of the semantic information such as zero padding or local versions. This operator also does not support prefix matching as the == operator does.

2 Likes