@@ -147,42 +147,89 @@ def _has_equality_pin(req: Requirement) -> bool:
147147 return len (specs ) == 1 and specs [0 ].operator == "==" and "*" not in specs [0 ].version
148148
149149
150+ def _get_toplevel_pinned_versions (
151+ ctx : context .WorkContext , req : Requirement
152+ ) -> frozenset [Version ]:
153+ """Return versions of *req* that have a top-level exact ``==`` pin in the graph."""
154+ top_level_edges = ctx .dependency_graph .get_root_node ().get_outgoing_edges (
155+ req .name , RequirementType .TOP_LEVEL
156+ )
157+ return frozenset (
158+ edge .destination_node .version
159+ for edge in top_level_edges
160+ if _has_equality_pin (edge .req )
161+ )
162+
163+
164+ def _resolve_cooldown_params (
165+ ctx : context .WorkContext ,
166+ req : Requirement ,
167+ ) -> tuple [datetime .timedelta , datetime .datetime ] | None :
168+ """Resolve min_age and bootstrap_time for a package's cooldown.
169+
170+ Returns ``None`` when cooldown is disabled (no global/per-package
171+ configuration, or a per-package override of 0). Otherwise returns
172+ the effective ``(min_age, bootstrap_time)`` pair.
173+ """
174+ min_age_override = ctx .package_build_info (req ).resolver_min_release_age
175+
176+ if ctx .cooldown is None and min_age_override is None :
177+ return None
178+ if min_age_override == 0 :
179+ return None
180+
181+ if min_age_override is not None :
182+ min_age = datetime .timedelta (days = min_age_override )
183+ elif ctx .cooldown is not None :
184+ min_age = ctx .cooldown .min_age
185+ else :
186+ return None
187+
188+ bootstrap_time = (
189+ ctx .cooldown .bootstrap_time
190+ if ctx .cooldown is not None
191+ else datetime .datetime .now (datetime .UTC )
192+ )
193+ return min_age , bootstrap_time
194+
195+
150196def resolve_package_cooldown (
151197 ctx : context .WorkContext ,
152198 req : Requirement ,
153199 req_type : RequirementType | None = None ,
154200) -> Cooldown | None :
155201 """Compute the effective cooldown for a single package.
156202
157- Args:
158- ctx: The current work context (provides the global cooldown).
159- req: The package requirement being resolved.
160- req_type: The requirement type (top-level, install, etc.).
203+ Returns ``None`` (cooldown disabled) when:
204+
205+ * The requirement is a top-level exact ``==`` pin — the user explicitly
206+ approved that version.
207+ * A per-package ``min_release_age=0`` override disables cooldown.
208+ * No global cooldown is configured and no per-package override enables one.
161209
162- Returns:
163- The cooldown to pass to the provider, or ``None`` if disabled.
210+ Otherwise a ``Cooldown`` is returned with:
211+
212+ * *min_age* from the per-package override (if set) or the global cooldown.
213+ * *bootstrap_time* inherited from the global cooldown (for a consistent
214+ cutoff across the entire run) or the current time.
215+ * *exempt_versions* populated from top-level exact-pinned entries in the
216+ dependency graph, so transitive resolutions of the same package honour
217+ the user's explicit pin.
164218 """
165219 if req_type == RequirementType .TOP_LEVEL and _has_equality_pin (req ):
166220 if ctx .cooldown is not None :
167221 logger .info ("cooldown bypassed as the top-level requirement uses == pin" )
168222 return None
169223
170- per_package_days = ctx .package_build_info (req ).resolver_min_release_age
171- global_cooldown = ctx .cooldown
172- if per_package_days is None :
173- return global_cooldown
174- if per_package_days == 0 :
224+ params = _resolve_cooldown_params (ctx , req )
225+ if params is None :
175226 return None
176- # Per-package positive override: inherit bootstrap_time from global so all
177- # resolutions in a single run share the same fixed cutoff point.
178- bootstrap_time = (
179- global_cooldown .bootstrap_time
180- if global_cooldown is not None
181- else datetime .datetime .now (datetime .UTC )
182- )
227+
228+ min_age , bootstrap_time = params
183229 return Cooldown (
184- min_age = datetime . timedelta ( days = per_package_days ) ,
230+ min_age = min_age ,
185231 bootstrap_time = bootstrap_time ,
232+ exempt_versions = _get_toplevel_pinned_versions (ctx , req ),
186233 )
187234
188235
@@ -685,11 +732,12 @@ def is_satisfied_by(self, requirement: Requirement, candidate: Candidate) -> boo
685732 def is_blocked_by_cooldown (self , candidate : Candidate ) -> bool :
686733 """Return True if the candidate is rejected by the release-age cooldown."""
687734
688- # a cooldown is not specified...
689735 if self .cooldown is None :
690736 return False
691737
692- # the target candidate doesn't provide a valid upload timestamp
738+ if candidate .version in self .cooldown .exempt_versions :
739+ return False
740+
693741 if candidate .upload_time is None :
694742 if not self .supports_upload_time :
695743 # this provider does not yet support timestamp retrieval (e.g. GitHub).
0 commit comments