Skip to content

Commit 6245fed

Browse files
committed
Make resolvelib's provider capable of handling empty iterators
This is _technically_ possible with the API, and accounting for that enables the resolver to evolve with this information.
1 parent 7ff4da6 commit 6245fed

File tree

1 file changed

+26
-8
lines changed

1 file changed

+26
-8
lines changed

src/pip/_internal/resolution/resolvelib/provider.py

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -124,14 +124,29 @@ def get_preference( # type: ignore
124124
* If equal, prefer if any requirement is "pinned", i.e. contains
125125
operator ``===`` or ``==``.
126126
* If equal, calculate an approximate "depth" and resolve requirements
127-
closer to the user-specified requirements first.
127+
closer to the user-specified requirements first. If the depth cannot
128+
by determined (eg: due to no matching parents), it is considered
129+
infinite.
128130
* Order user-specified requirements by the order they are specified.
129131
* If equal, prefers "non-free" requirements, i.e. contains at least one
130132
operator, such as ``>=`` or ``<``.
131133
* If equal, order alphabetically for consistency (helps debuggability).
132134
"""
133-
lookups = (r.get_candidate_lookup() for r, _ in information[identifier])
134-
candidate, ireqs = zip(*lookups)
135+
try:
136+
next(iter(information[identifier]))
137+
except StopIteration:
138+
# There is no information for this identifier, so there's no known
139+
# candidates.
140+
has_information = False
141+
else:
142+
has_information = True
143+
144+
if has_information:
145+
lookups = (r.get_candidate_lookup() for r, _ in information[identifier])
146+
candidate, ireqs = zip(*lookups)
147+
else:
148+
candidate, ireqs = None, ()
149+
135150
operators = [
136151
specifier.operator
137152
for specifier_set in (ireq.specifier for ireq in ireqs if ireq)
@@ -146,11 +161,14 @@ def get_preference( # type: ignore
146161
requested_order: Union[int, float] = self._user_requested[identifier]
147162
except KeyError:
148163
requested_order = math.inf
149-
parent_depths = (
150-
self._known_depths[parent.name] if parent is not None else 0.0
151-
for _, parent in information[identifier]
152-
)
153-
inferred_depth = min(d for d in parent_depths) + 1.0
164+
if has_information:
165+
parent_depths = (
166+
self._known_depths[parent.name] if parent is not None else 0.0
167+
for _, parent in information[identifier]
168+
)
169+
inferred_depth = min(d for d in parent_depths) + 1.0
170+
else:
171+
inferred_depth = math.inf
154172
else:
155173
inferred_depth = 1.0
156174
self._known_depths[identifier] = inferred_depth

0 commit comments

Comments
 (0)