Spec change/bugfix: dependency specifiers simplification (PEP 508)

I missed the thread when initially posted, but belatedly saw the PR at fix(markers): Fix/change dependency specifiers by henryiii · Pull Request #1971 · pypa/packaging.python.org · GitHub

I agree with the intent of the change, but the technical details need to be tightened up, as == version matching is also only valid for actual version specifiers (due to things like zero padding, prefix matching, etc). This means that when nominal versions aren’t actually valid versions, the fallback from all of ==, != ~=, >= and <= should be to === (negated in the != case), with only < and > unaffected (and necessarily returning false).

We may also need to tighten up the definition of === further - it was cleaned up last year to be explicitly case insensitive, but remains silent on the question of how leading and trailing whitespace should be handled.

There are also two paths to handling the clarification of how non-version fields should be compared:

  • comparison is defined in terms of === arbitrary equivalence
  • comparison is defined in terms of a regular Python string comparison operation

The former approach can be consistently applied to all of string-only fields, string-or-version fields, and nominally version fields that fail parsing as versions.

The latter approach is potentially viable (and more closely matches the status quo), but creates ambiguity around case sensitivity for string-or-version fields.

Edit: After posting, I also considered whether we could just say that == in environment markers never means version matching and is always a regular Python string comparison. However, that doesn’t work, as we genuinely want python_version and python_full_version (and, to a lesser degree, implementation_version and even platform_version), to follow the same rules for things like zero padding as dependency version specifiers do)