Skip to content

Commit a0651a2

Browse files
committed
Fix Marker non-version-to-version eval failing
As described in my previous commit to add test cases covering this behaviour, PEP 508 - Environment Markers section specifies that markers are evaluated using version operator rules when both sides are valid versions, and otherwise regular python operator rules apply. However, the implementation was failing to handle the case where the RHS was a valid version specifier, but the LHS was not a valid version. In this case, PEP 508 requires the comparison falls back to python rules, but the implementation was throwing InvalidVersion. The implementation now matches the behaviour in the spec, as we now check that both the LHS and the RHS are versions before attempting version comparison (not just the RHS as before).
1 parent a861e17 commit a0651a2

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed

src/packaging/markers.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from ._tokenizer import ParserSyntaxError
1616
from .specifiers import InvalidSpecifier, Specifier
1717
from .utils import canonicalize_name
18+
from .version import InvalidVersion, Version
1819

1920
__all__ = [
2021
"InvalidMarker",
@@ -175,12 +176,20 @@ def _format_marker(
175176

176177

177178
def _eval_op(lhs: str, op: Op, rhs: str) -> bool:
179+
# PEP 508 - Environment Markers
180+
# https://peps.python.org/pep-0508/#environment-markers
181+
# > The <version_cmp> operators use the PEP 440 version comparison rules
182+
# > when those are defined (that is when both sides have a valid version
183+
# > specifier). If there is no defined PEP 440 behaviour and the operator
184+
# > exists in Python, then the operator falls back to the Python behaviour.
185+
# > Otherwise an error should be raised.
178186
try:
179187
spec = Specifier("".join([op.serialize(), rhs]))
180-
except InvalidSpecifier:
188+
lhs_ver = Version(lhs)
189+
except (InvalidSpecifier, InvalidVersion):
181190
pass
182191
else:
183-
return spec.contains(lhs, prereleases=True)
192+
return spec.contains(lhs_ver, prereleases=True)
184193

185194
oper: Operator | None = _operators.get(op.serialize())
186195
if oper is None:

0 commit comments

Comments
 (0)