Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions src/packaging/markers.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,8 @@ def _normalize(
# > compared using the semantics outlined in PEP 503 for names
if key == "extra":
assert isinstance(rhs, str), "extra value must be a string"
return (canonicalize_name(lhs), canonicalize_name(rhs))
# Both sides are normalized at this point already
return (lhs, rhs)
if key in MARKERS_ALLOWING_SET:
if isinstance(rhs, str): # pragma: no cover
return (canonicalize_name(lhs), canonicalize_name(rhs))
Expand Down Expand Up @@ -351,12 +352,15 @@ def evaluate(
)
elif context == "metadata":
current_environment["extra"] = ""

if environment is not None:
current_environment.update(environment)
# The API used to allow setting extra to None. We need to handle this
# case for backwards compatibility.
if "extra" in current_environment and current_environment["extra"] is None:
current_environment["extra"] = ""
if "extra" in current_environment:
# The API used to allow setting extra to None. We need to handle
# this case for backwards compatibility. Also skip running
# normalize name if extra is empty.
extra = cast("str | None", current_environment["extra"])
current_environment["extra"] = canonicalize_name(extra) if extra else ""

return _evaluate_markers(
self._markers, _repair_python_full_version(current_environment)
Expand Down
7 changes: 7 additions & 0 deletions tests/test_markers.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,13 @@ def test_environment_with_extra_none(self) -> None:
# THEN
assert marker.evaluate(environment) is False

def test_environment_with_no_extras(self) -> None:
# Environment is set but no 'extra' key is present; branch only hit on
# non-metadata context.
marker = Marker("os_name == 'foo'")
assert marker.evaluate({"os_name": "foo"}, context="requirement")
assert not marker.evaluate({"os_name": "bar"}, context="requirement")

@pytest.mark.parametrize(
("marker_string", "environment", "expected"),
[
Expand Down
Loading