Skip to content

Commit ec5c4e1

Browse files
committed
Correct PythonInputProvider._iter_matches to fix tests with packaging 26.0
1 parent ebdb68e commit ec5c4e1

File tree

1 file changed

+22
-7
lines changed

1 file changed

+22
-7
lines changed

tests/functional/python/test_resolvers_python.py

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
import operator
44
import os
55
from collections import defaultdict
6+
from functools import reduce
67

78
import packaging.markers
89
import packaging.requirements
10+
import packaging.specifiers
911
import packaging.utils
1012
import packaging.version
1113
import pytest
@@ -92,12 +94,23 @@ def _iter_matches(self, identifier, requirements, incompatibilities):
9294
name, _, _ = identifier.partition("[")
9395
bad_versions = {c.version for c in incompatibilities[identifier]}
9496
extras = {e for r in requirements[identifier] for e in r.extras}
95-
for key in self.index[name]:
96-
v = packaging.version.parse(key)
97-
if any(v not in r.specifier for r in requirements[identifier]):
98-
continue
99-
if v in bad_versions:
100-
continue
97+
98+
# Get all versions from the index, excluding bad versions
99+
available_versions = (
100+
v
101+
for key in self.index[name]
102+
if (v := packaging.version.parse(key)) not in bad_versions
103+
)
104+
105+
# Combine all requirement specifiers using & operator
106+
combined_specifier = reduce(
107+
operator.and_,
108+
map(operator.attrgetter("specifier"), requirements[identifier]),
109+
packaging.specifiers.SpecifierSet(),
110+
)
111+
112+
# Filter versions using the combined specifier
113+
for v in combined_specifier.filter(available_versions):
101114
yield Candidate(name=name, version=v, extras=extras)
102115

103116
def find_matches(self, identifier, requirements, incompatibilities):
@@ -109,7 +122,9 @@ def find_matches(self, identifier, requirements, incompatibilities):
109122
return candidates
110123

111124
def is_satisfied_by(self, requirement, candidate):
112-
return candidate.version in requirement.specifier
125+
# Use prereleases=None to follow PEP 440: only include pre-releases
126+
# if the specifier explicitly mentions them
127+
return requirement.specifier.contains(candidate.version, prereleases=None)
113128

114129
def _iter_dependencies(self, candidate):
115130
name = packaging.utils.canonicalize_name(candidate.name)

0 commit comments

Comments
 (0)