Skip to content

Marker version comparison fails when the marker variable is on the RHS of a term. #934

@jsirois

Description

@jsirois

As far as I can tell, the markers spec1 does not limit the position of marker variables in term expressions and they are allowed to appear on the right hand side. It's true the examples in the spec exclusively use the LHS, but the very explicit grammar23 write up doubles down on allowing marker variables on either side of a term.

For example, although normally spelled python_version >= '3.9', you should be able to say '3.9' <= python_version to the same end. Now you ~can run that example, but an issue similar to #633 is hidden. I expose the issue in the == '3.13.*' example below though:

:; pex packaging
Pex 2.55.2 ephemeral hermetic environment with 1 requirement and 1 activated distribution.
Python 3.13.7 (main, Aug 15 2025, 11:40:50) [GCC 14.2.0] on linux
Type "help", "pex", "copyright", "credits" or "license" for more information.
>>> pex()
Running from ephemeral loose PEX directory: /tmp/tmpixmwdi3m
Requirements:
  packaging
Activated Distributions:
  packaging-25.0-py3-none-any.whl
>>> from packaging.markers import Marker
>>> Marker("python_version >= '3.9'").evaluate()
True
>>> Marker("'3.9' <= python_version").evaluate()
True
>>> Marker("python_full_version == '3.13.*'").evaluate()
True
>>> Marker("'3.13.*' == python_full_version").evaluate()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/jsirois/.cache/pex/installed_wheels/0/29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484/packaging-25.0-py3-none-any.whl/packaging/markers.py", line 347, in evaluate
    return _evaluate_markers(
        self._markers, _repair_python_full_version(current_environment)
    )
  File "/home/jsirois/.cache/pex/installed_wheels/0/29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484/packaging-25.0-py3-none-any.whl/packaging/markers.py", line 239, in _evaluate_markers
    groups[-1].append(_eval_op(lhs_value, op, rhs_value))
                      ~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jsirois/.cache/pex/installed_wheels/0/29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484/packaging-25.0-py3-none-any.whl/packaging/markers.py", line 187, in _eval_op
    return spec.contains(lhs, prereleases=True)
           ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jsirois/.cache/pex/installed_wheels/0/29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484/packaging-25.0-py3-none-any.whl/packaging/specifiers.py", line 552, in contains
    normalized_item = _coerce_version(item)
  File "/home/jsirois/.cache/pex/installed_wheels/0/29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484/packaging-25.0-py3-none-any.whl/packaging/specifiers.py", line 28, in _coerce_version
    version = Version(version)
  File "/home/jsirois/.cache/pex/installed_wheels/0/29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484/packaging-25.0-py3-none-any.whl/packaging/version.py", line 202, in __init__
    raise InvalidVersion(f"Invalid version: {version!r}")
packaging.version.InvalidVersion: Invalid version: '3.13.*'
>>>

Unless I've misread the spec, this seems like a bug; otherwise, the spec has a bug. I personally think the spec has a bug, allowing more flexibility than needed; it should just mandate marker variables can only appear on the LHS of terms.

Footnotes

  1. https://packaging.python.org/en/latest/specifications/dependency-specifiers/#environment-markers

  2. https://packaging.python.org/en/latest/specifications/dependency-specifiers/#grammar

  3. https://packaging.python.org/en/latest/specifications/dependency-specifiers/#complete-grammar

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions