diff --git a/packaging/markers.py b/packaging/markers.py index 399051489..1d61adaff 100644 --- a/packaging/markers.py +++ b/packaging/markers.py @@ -5,6 +5,7 @@ import operator import os import platform +import re import sys from typing import Any, Callable, Dict, List, Optional, Tuple, Union @@ -219,6 +220,16 @@ def _get_env(environment: Dict[str, str], name: str) -> str: return value +def _normalize(*values: str, key: str) -> Tuple[str, ...]: + # PEP 685 – Comparison of extra names for optional distribution dependencies + # https://peps.python.org/pep-0685/ + if key == "extra": + return tuple(re.sub(r"[-_.]+", "-", v).lower() for v in values) + + # other environment markes don't have such standards + return values + + def _evaluate_markers(markers: List[Any], environment: Dict[str, str]) -> bool: groups: List[List[bool]] = [[]] @@ -231,12 +242,15 @@ def _evaluate_markers(markers: List[Any], environment: Dict[str, str]) -> bool: lhs, op, rhs = marker if isinstance(lhs, Variable): - lhs_value = _get_env(environment, lhs.value) + environment_key = lhs.value + lhs_value = _get_env(environment, environment_key) rhs_value = rhs.value else: lhs_value = lhs.value - rhs_value = _get_env(environment, rhs.value) + environment_key = rhs.value + rhs_value = _get_env(environment, environment_key) + lhs_value, rhs_value = _normalize(lhs_value, rhs_value, key=environment_key) groups[-1].append(_eval_op(lhs_value, op, rhs_value)) else: assert marker in ["and", "or"] diff --git a/tests/test_markers.py b/tests/test_markers.py index 0a16ff277..b1ccf63c6 100644 --- a/tests/test_markers.py +++ b/tests/test_markers.py @@ -292,6 +292,14 @@ def test_extra_with_no_extra_in_environment(self): ), ("extra == 'security'", {"extra": "quux"}, False), ("extra == 'security'", {"extra": "security"}, True), + ("extra == 'SECURITY'", {"extra": "security"}, True), + ("extra == 'security'", {"extra": "SECURITY"}, True), + ("extra == 'pep-685-norm'", {"extra": "PEP_685...norm"}, True), + ( + "extra == 'Different.punctuation..is...equal'", + {"extra": "different__punctuation_is_EQUAL"}, + True, + ), ], ) def test_evaluates(self, marker_string, environment, expected):