@@ -179,7 +179,10 @@ def unpack_url(
179
179
180
180
181
181
def _check_download_dir (
182
- link : Link , download_dir : str , hashes : Optional [Hashes ]
182
+ link : Link ,
183
+ download_dir : str ,
184
+ hashes : Optional [Hashes ],
185
+ warn_on_hash_mismatch : bool = True ,
183
186
) -> Optional [str ]:
184
187
"""Check download_dir for previously downloaded file with correct hash
185
188
If a correct file is found return its path else None
@@ -195,10 +198,11 @@ def _check_download_dir(
195
198
try :
196
199
hashes .check_against_path (download_path )
197
200
except HashMismatch :
198
- logger .warning (
199
- "Previously-downloaded file %s has bad hash. Re-downloading." ,
200
- download_path ,
201
- )
201
+ if warn_on_hash_mismatch :
202
+ logger .warning (
203
+ "Previously-downloaded file %s has bad hash. Re-downloading." ,
204
+ download_path ,
205
+ )
202
206
os .unlink (download_path )
203
207
return None
204
208
return download_path
@@ -263,7 +267,7 @@ def __init__(
263
267
264
268
def _log_preparing_link (self , req : InstallRequirement ) -> None :
265
269
"""Provide context for the requirement being prepared."""
266
- if req .link .is_file and not req .original_link_is_in_wheel_cache :
270
+ if req .link .is_file and not req .is_wheel_from_cache :
267
271
message = "Processing %s"
268
272
information = str (display_path (req .link .file_path ))
269
273
else :
@@ -284,7 +288,7 @@ def _log_preparing_link(self, req: InstallRequirement) -> None:
284
288
self ._previous_requirement_header = (message , information )
285
289
logger .info (message , information )
286
290
287
- if req .original_link_is_in_wheel_cache :
291
+ if req .is_wheel_from_cache :
288
292
with indent_log ():
289
293
logger .info ("Using cached %s" , req .link .filename )
290
294
@@ -485,7 +489,18 @@ def prepare_linked_requirement(
485
489
file_path = None
486
490
if self .download_dir is not None and req .link .is_wheel :
487
491
hashes = self ._get_linked_req_hashes (req )
488
- file_path = _check_download_dir (req .link , self .download_dir , hashes )
492
+ file_path = _check_download_dir (
493
+ req .link ,
494
+ self .download_dir ,
495
+ hashes ,
496
+ # When a locally built wheel has been found in cache, we don't warn
497
+ # about re-downloading when the already downloaded wheel hash does
498
+ # not match. This is because the hash must be checked against the
499
+ # original link, not the cached link. It that case the already
500
+ # downloaded file will be removed and re-fetched from cache (which
501
+ # implies a hash check against the cache entry's origin.json).
502
+ warn_on_hash_mismatch = not req .is_wheel_from_cache ,
503
+ )
489
504
490
505
if file_path is not None :
491
506
# The file is already available, so mark it as downloaded
@@ -536,9 +551,35 @@ def _prepare_linked_requirement(
536
551
assert req .link
537
552
link = req .link
538
553
539
- self ._ensure_link_req_src_dir (req , parallel_builds )
540
554
hashes = self ._get_linked_req_hashes (req )
541
555
556
+ if hashes and req .is_wheel_from_cache :
557
+ assert req .download_info is not None
558
+ assert link .is_wheel
559
+ assert link .is_file
560
+ # We need to verify hashes, and we have found the requirement in the cache
561
+ # of locally built wheels.
562
+ if (
563
+ isinstance (req .download_info .info , ArchiveInfo )
564
+ and req .download_info .info .hashes
565
+ and hashes .has_one_of (req .download_info .info .hashes )
566
+ ):
567
+ # At this point we know the requirement was built from a hashable source
568
+ # artifact, and we verified that the cache entry's hash of the original
569
+ # artifact matches one of the hashes we expect. We don't verify hashes
570
+ # against the cached wheel, because the wheel is not the original.
571
+ hashes = None
572
+ else :
573
+ logger .warning (
574
+ "The hashes of the source archive found in cache entry "
575
+ "don't match, ignoring cached built wheel "
576
+ "and re-downloading source."
577
+ )
578
+ req .link = req .cached_wheel_source_link
579
+ link = req .link
580
+
581
+ self ._ensure_link_req_src_dir (req , parallel_builds )
582
+
542
583
if link .is_existing_dir ():
543
584
local_file = None
544
585
elif link .url not in self ._downloaded :
0 commit comments