Don't set _dist until it has been validated

Previously a call to `_fetch_metadata` could result in several possible
outcomes:

1. `_dist` set, `_provided` not set, dist returned - for lazy wheels
2. `_dist` set, `_provided` not set, exception - for bad lazy wheels
3. `_dist` not set, `_provided` not set, exception - for non-lazy req
   exceptions
4. `_dist` set, `_provided` not set, exception - for bad non-lazy reqs
5. `_dist` set, `_provided` set, dist returned - for non-lazy reqs

and probably more.

Our intent is to use `_dist` being set as the indicator of "this
requirement has been fully processed successfully" and discard
`_prepared`, since we don't actually rely on any of the other states
(they simply lead to a failure or in the future a retry).
This commit is contained in:
Chris Hunt 2020-08-02 11:04:27 -04:00
parent 89d8cba55b
commit d957cc94c8
1 changed files with 9 additions and 8 deletions

View File

@ -203,12 +203,11 @@ class _InstallRequirementBackedCandidate(Candidate):
# type: () -> Distribution
raise NotImplementedError("Override in subclass")
def _check_metadata_consistency(self):
# type: () -> None
def _check_metadata_consistency(self, dist):
# type: (Distribution) -> None
"""Check for consistency of project name and version of dist."""
# TODO: (Longer term) Rather than abort, reject this candidate
# and backtrack. This would need resolvelib support.
dist = self._dist # type: Distribution
name = canonicalize_name(dist.project_name)
if self._name is not None and self._name != name:
raise MetadataInconsistent(self._ireq, "name", dist.project_name)
@ -221,13 +220,14 @@ class _InstallRequirementBackedCandidate(Candidate):
if self._prepared:
return
try:
self._dist = self._prepare_distribution()
dist = self._prepare_distribution()
except HashError as e:
e.req = self._ireq
raise
assert self._dist is not None, "Distribution already installed"
self._check_metadata_consistency()
assert dist is not None, "Distribution already installed"
self._check_metadata_consistency(dist)
self._dist = dist
self._prepared = True
def _fetch_metadata(self):
@ -247,8 +247,9 @@ class _InstallRequirementBackedCandidate(Candidate):
)
url = self._link.url.split('#', 1)[0]
session = preparer.downloader._session
self._dist = dist_from_wheel_url(self._name, url, session)
self._check_metadata_consistency()
dist = dist_from_wheel_url(self._name, url, session)
self._check_metadata_consistency(dist)
self._dist = dist
if self._dist is None:
self._prepare()