@@ -579,16 +579,71 @@ def prepare_linked_requirement(
579579 # None of the optimizations worked, fully prepare the requirement
580580 return self ._prepare_linked_requirement (req , parallel_builds )
581581
582- def prepare_linked_requirements_more (
582+ def _extract_download_info (self , reqs : Iterable [InstallRequirement ]) -> None :
583+ """
584+ `pip install --report` extracts the download info from each requirement for its
585+ JSON output, so we need to make sure every requirement has this before finishing
586+ the resolve. But .download_info will only be populated by the point this method
587+ is called for requirements already found in the wheel cache, so we need to
588+ synthesize it for uncached results. Luckily, a DirectUrl can be parsed directly
589+ from a url without any other context. However, this also means the download info
590+ will only contain a hash if the link itself declares the hash.
591+ """
592+ for req in reqs :
593+ if req .download_info is None :
594+ self ._ensure_download_info (req )
595+
596+ def _force_fully_prepared (
597+ self , reqs : Iterable [InstallRequirement ], assert_has_dist_files : bool
598+ ) -> None :
599+ """
600+ The legacy resolver seems to prepare requirements differently that can leave
601+ them half-done in certain code paths. I'm not quite sure how it's doing things,
602+ but at least we can do this to make sure they do things right.
603+ """
604+ for req in reqs :
605+ req .prepared = True
606+ if assert_has_dist_files :
607+ assert req .is_concrete
608+
609+ def _ensure_dist_files (
583610 self , reqs : Iterable [InstallRequirement ], parallel_builds : bool = False
584611 ) -> None :
585- """Prepare linked requirements more, if needed ."""
612+ """Download any metadata-only linked requirements ."""
586613 metadata_only_reqs = [req for req in reqs if not req .is_concrete ]
587614 self ._complete_partial_requirements (
588615 metadata_only_reqs ,
589616 parallel_builds = parallel_builds ,
590617 )
591618
619+ def finalize_linked_requirements (
620+ self ,
621+ reqs : Iterable [InstallRequirement ],
622+ require_dist_files : bool ,
623+ parallel_builds : bool = False ,
624+ ) -> None :
625+ """Prepare linked requirements more, if needed.
626+
627+ Neighboring .metadata files as per PEP 658 or lazy wheels via fast-deps will be
628+ preferred to extract metadata from any concrete requirement (one that has been
629+ mapped to a Link) without downloading the underlying wheel or sdist. When ``pip
630+ install --dry-run`` is called, we want to avoid ever downloading the underlying
631+ dist, but we still need to provide all of the results that pip commands expect
632+ from the typical resolve process.
633+
634+ Those expectations vary, but one distinction lies in whether the command needs
635+ an actual physical dist somewhere on the filesystem, or just the metadata about
636+ it from the resolver (as in ``pip install --report``). If the command requires
637+ actual physical filesystem locations for the resolved dists, it must call this
638+ method with ``require_dist_files=True`` to fully download anything
639+ that remains.
640+ """
641+ if require_dist_files :
642+ self ._ensure_dist_files (reqs , parallel_builds = parallel_builds )
643+ else :
644+ self ._extract_download_info (reqs )
645+ self ._force_fully_prepared (reqs , assert_has_dist_files = require_dist_files )
646+
592647 def _ensure_local_file_path (
593648 self , req : InstallRequirement , hashes : Optional [Hashes ]
594649 ) -> None :
0 commit comments