@@ -166,14 +166,20 @@ def get_preference(
166166
167167 Currently pip considers the following in order:
168168
169- * Prefer if any of the known requirements is "direct", e.g. points to an
170- explicit URL.
171- * If equal, prefer if any requirement is "pinned", i.e. contains
172- operator ``===`` or ``==``.
173- * Order user-specified requirements by the order they are specified.
174- * If equal, prefers "non-free" requirements, i.e. contains at least one
175- operator, such as ``>=`` or ``<``.
176- * If equal, order alphabetically for consistency (helps debuggability).
169+ * Any requirement that is "direct", e.g., points to an explicit URL.
170+ * Any requirement that is "pinned", i.e., contains the operator ``===``
171+ or ``==`` without a wildcard.
172+ * Any requirement that imposes an upper version limit, i.e., contains the
173+ operator ``<``, ``<=``, ``~=``, or ``==`` with a wildcard. Because
174+ pip prioritizes the latest version, preferring explicit upper bounds
175+ can rule out infeasible candidates sooner. This does not imply that
176+ upper bounds are good practice; they can make dependency management
177+ and resolution harder.
178+ * Order user-specified requirements as they are specified, placing
179+ other requirements afterward.
180+ * Any "non-free" requirement, i.e., one that contains at least one
181+ operator, such as ``>=`` or ``!=``.
182+ * Alphabetical order for consistency (aids debuggability).
177183 """
178184 try :
179185 next (iter (information [identifier ]))
@@ -206,12 +212,17 @@ def get_preference(
206212 ]
207213
208214 pinned = any (((op [:2 ] == "==" ) and ("*" not in ver )) for op , ver in operators )
215+ upper_bounded = any (
216+ ((op in ("<" , "<=" , "~=" )) or (op == "==" and "*" in ver ))
217+ for op , ver in operators
218+ )
209219 unfree = bool (operators )
210220 requested_order = self ._user_requested .get (identifier , math .inf )
211221
212222 return (
213223 not direct ,
214224 not pinned ,
225+ not upper_bounded ,
215226 requested_order ,
216227 not unfree ,
217228 identifier ,
@@ -263,6 +274,7 @@ def _eligible_for_upgrade(identifier: str) -> bool:
263274 def is_satisfied_by (self , requirement : Requirement , candidate : Candidate ) -> bool :
264275 return requirement .is_satisfied_by (candidate )
265276
266- def get_dependencies (self , candidate : Candidate ) -> Sequence [Requirement ]:
277+ def get_dependencies (self , candidate : Candidate ) -> Iterable [Requirement ]:
267278 with_requires = not self ._ignore_dependencies
268- return [r for r in candidate .iter_dependencies (with_requires ) if r is not None ]
279+ # iter_dependencies() can perform nontrivial work so delay until needed.
280+ return (r for r in candidate .iter_dependencies (with_requires ) if r is not None )
0 commit comments