Fix marker version comparison when variable is on the RHS (issue #934)#1126
Open
Fix marker version comparison when variable is on the RHS (issue #934)#1126
Conversation
Fixes pypa#934. PEP 508 allows marker expressions with the variable on either side, e.g.: python_version >= '3.9' '3.9' <= python_version # equivalent Previously _evaluate_markers passed the operands to _eval_op in the original (possibly reversed) order without adjusting for the direction. For version-comparison operators this caused _eval_op to construct a Specifier from the environment value (e.g. '3.13.7') and then check containment of the literal pattern ('3.13.*'), which failed because the wildcard is not a valid version string. Fix: thread an invert flag through _eval_op. When the marker variable was on the RHS and the operator is a directional comparison (not 'in' / 'not in'), swap the operands back and flip the operator so the Specifier is always built from the literal and the environment value is the thing being checked. Membership operators (in / not in) already work correctly in either direction and are left untouched. Add regression tests covering ==, <=, > with version markers and == / != with non-version markers when the variable is on the RHS.
Contributor
|
Duplicate of #1112. Not sure if we want to do this still. |
brettcannon
approved these changes
Mar 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #934.
PEP 508 permits marker expressions with the variable on either side:
Root cause
_eval_opalways builds aSpecifierfrom itsrhsargument and then checks whetherlhsis contained in it._evaluate_markerswas passing operands in the original (possibly reversed) order without adjusting for direction, so when the variable was on the RHS the Specifier was constructed from the environment value (e.g.'3.13.7') and the literal pattern ('3.13.*') was used as the containment query — which fails because a wildcard is not a valid plain version string.Fix
An
invertflag is threaded into_eval_op. When the marker variable was on the RHS and the operator is a directional comparison (i.e. notin/not in),_eval_opswaps the operands and flips the operator (e.g.<=→>=) so the Specifier is always built from the literal and the environment value is what gets checked.Membership operators (
in/not in) already handle both directions correctly and are left untouched.Tests added
Seven new parametrised cases in
TestMarker.test_marker_variable_on_rhs:'3.13.*' == python_full_version3.13.7True'3.13.*' == python_full_version3.14.0False'3.9' <= python_version3.13True'3.14' > python_version3.13True'3.14' > python_version3.15False'posix' == os_nameposixTrue'nt' != os_nameposixTrueFull test suite: 60 634 passed, 1 skipped (the skip is an unrelated Linux-only test).