diff --git a/news/13252.bugfix.rst b/news/13252.bugfix.rst new file mode 100644 index 00000000000..47737458964 --- /dev/null +++ b/news/13252.bugfix.rst @@ -0,0 +1,3 @@ +When choosing a preferred requirement for resolving dependencies +do not consider a specifier with a * in it, e.g. "==1.*", to be a +pinned specifier. diff --git a/src/pip/_internal/resolution/resolvelib/provider.py b/src/pip/_internal/resolution/resolvelib/provider.py index 74cdb9d80f9..40326001eaa 100644 --- a/src/pip/_internal/resolution/resolvelib/provider.py +++ b/src/pip/_internal/resolution/resolvelib/provider.py @@ -142,14 +142,14 @@ def get_preference( else: candidate, ireqs = None, () - operators = [ - specifier.operator + operators: list[tuple[str, str]] = [ + (specifier.operator, specifier.version) for specifier_set in (ireq.specifier for ireq in ireqs if ireq) for specifier in specifier_set ] direct = candidate is not None - pinned = any(op[:2] == "==" for op in operators) + pinned = any(((op[:2] == "==") and ("*" not in ver)) for op, ver in operators) unfree = bool(operators) requested_order = self._user_requested.get(identifier, math.inf) diff --git a/tests/unit/resolution_resolvelib/test_provider.py b/tests/unit/resolution_resolvelib/test_provider.py index 45536a9eab3..d37076a9356 100644 --- a/tests/unit/resolution_resolvelib/test_provider.py +++ b/tests/unit/resolution_resolvelib/test_provider.py @@ -52,6 +52,14 @@ def build_req_info( {}, (True, False, False, True, math.inf, False, "pinned-package"), ), + # Star-specified package, i.e. with "*" + ( + "star-specified-package", + {"star-specified-package": [build_req_info("star-specified-package==1.*")]}, + [], + {}, + (True, False, True, True, math.inf, False, "star-specified-package"), + ), # Package that caused backtracking ( "backtrack-package",