Skip to content

Commit

Permalink
first pass at improving the metadata-only dist control flow
Browse files Browse the repository at this point in the history
  • Loading branch information
cosmicexplorer committed Jul 31, 2023
1 parent 4b7fd38 commit a168a45
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 8 deletions.
20 changes: 15 additions & 5 deletions src/pip/_internal/operations/prepare.py
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,9 @@ def _fetch_metadata_only(
"Metadata-only fetching is not used in the legacy resolver",
)
return None
# TODO: this should probably not be checked here, but rather later once we
# download the wheels? Otherwise hash checking won't be able to use
# metadata-only dists at all.
if self.require_hashes:
logger.debug(
"Metadata-only fetching is not used as hash checking is required",
Expand Down Expand Up @@ -522,7 +525,7 @@ def prepare_linked_requirement(
# These reqs now have the dependency information from the downloaded
# metadata, without having downloaded the actual dist at all.
req.dist_from_metadata = metadata_dist
req.needs_more_preparation = True
req.is_virtual_metadata_only_dist = True
return metadata_dist

# None of the optimizations worked, fully prepare the requirement
Expand Down Expand Up @@ -551,7 +554,9 @@ def _force_fully_prepared(self, reqs: Iterable[InstallRequirement]) -> None:
"""
for req in reqs:
req.prepared = True
req.needs_more_preparation = False
# TODO: this is really hacky, because the requirement may well still be
# metadata-only at the end of the resolve when this is called.
req.is_virtual_metadata_only_dist = False

def finalize_linked_requirements(
self,
Expand Down Expand Up @@ -580,7 +585,7 @@ def finalize_linked_requirements(
self._force_fully_prepared(reqs)
return

reqs = [req for req in reqs if req.needs_more_preparation]
reqs = [req for req in reqs if req.is_virtual_metadata_only_dist]
for req in reqs:
# Determine if any of these requirements were already downloaded.
if self.download_dir is not None and req.link.is_wheel:
Expand All @@ -590,13 +595,13 @@ def finalize_linked_requirements(
self._downloaded[req.link.url] = file_path
# This is a wheel, so we know there's nothing more we need to do to
# prepare it.
req.needs_more_preparation = False
req.is_virtual_metadata_only_dist = False

# Prepare requirements we found were already downloaded for some
# reason. The other downloads will be completed separately.
partially_downloaded_reqs: List[InstallRequirement] = []
for req in reqs:
if req.needs_more_preparation:
if req.is_virtual_metadata_only_dist:
partially_downloaded_reqs.append(req)
else:
self._prepare_linked_requirement(req, parallel_builds)
Expand Down Expand Up @@ -700,11 +705,16 @@ def _prepare_linked_requirement(
self.build_isolation,
self.check_build_deps,
)
# At this point, the requirement should have .metadata_directory or
# .local_file_path set, so we can unset this and allow it to resolve the real
# dist from .get_dist().
req.is_virtual_metadata_only_dist = False
return dist

def save_linked_requirement(self, req: InstallRequirement) -> None:
assert self.download_dir is not None
assert req.link is not None
assert not req.is_virtual_metadata_only_dist
link = req.link
if link.is_vcs or (link.is_existing_dir() and req.editable):
# Make a .zip of the source_dir we already created.
Expand Down
12 changes: 9 additions & 3 deletions src/pip/_internal/req/req_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ def __init__(
self.hash_options = hash_options if hash_options else {}
self.config_settings = config_settings
# Set to True after successful preparation of this requirement
# TODO: this is only used in the legacy resolver: remove this!
self.prepared = False
# User supplied requirement are explicitly requested for installation
# by the user via CLI arguments or requirements files, as opposed to,
Expand Down Expand Up @@ -180,11 +181,14 @@ def __init__(
# but after loading this flag should be treated as read only.
self.use_pep517 = use_pep517

# This requirement needs more preparation before it can be built
self.needs_more_preparation = False
# This requirement's dist from get_dist() was synthesized from PEP 658 or
# fast-deps metadata, and needs to be downloaded and further prepared for any
# downstream tasks that require actual dists (which is all of them except
# `install --dry-run`).
self.is_virtual_metadata_only_dist = False

# Distribution from the .metadata file referenced by the PEP 658
# data-dist-info-metadata attribute.
# data-dist-info-metadata attribute, or from fast-deps.
self.dist_from_metadata: Optional[BaseDistribution] = None

def __str__(self) -> str:
Expand Down Expand Up @@ -593,6 +597,8 @@ def metadata(self) -> Any:

return self._metadata

# TODO: avoid recomputing this, and instead cache it on the InstallRequirement
# object once it is resolved by the prepare_linked_requirement() method.
def get_dist(self) -> BaseDistribution:
if self.metadata_directory:
return get_directory_distribution(self.metadata_directory)
Expand Down

0 comments on commit a168a45

Please sign in to comment.