The fact that all of this functionality can be put in terms of the
`RequirementPreparer` indicates that, at least at this point, this is
the cleanest place to put this functionality.
These are things we know will be true because of the existing wheel
processing. In the future we may delegate the extraction of these to the
LinkCandidate itself so it doesn't have to be an assertion.
We happen to know that this is the same treatment that gave us `_name`
and `_version` for Wheels in the first place (in `LinkEvaluator`). It's not
ideal, however the metadata consistency check that occurs in `Candidate`
after creation of a `Distribution` guards us against any deviation in
the name and version during our processing.
Reduces dependence on Candidate.
Since wheels can't be editable, we can move this into LinkCandidate,
closer to `RequirementPreparer.prepare_linked_requirement` into which we
want to integrate `_fetch_metadata`.
Instead of an early return, we fall through to the existing check at the
end of this function. This aligns our treatment of `_fetch_metadata` and
`_prepare_distribution`.
Since `_prepare` is called in two places, we preserve the
`if self._dist is not None` protection above the new call to
`_fetch_metadata`. The second `if` in `_prepare` handles the early
return required when processing a lazy wheel.
Now that `_dist` is only set on success, we can use it to guard against
repeated execution instead of `_prepared`. As a result there are now only
two possible outcomes for calling `dist`:
1. `_dist` set and returned - lazy and non-lazy req
2. `_dist` not set and exception raised - bad lazy or bad non-lazy req
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 check only applies to explicit requirements since we avoid
downloading the dist from finder altogether when there is a matching
installation (although the check wouldn’t change the behaviour in that
case anyway).
We can do this when we build the `ExplicitRequirement` instead, like how
we did for `SpecifierRequirement`, but that would require us to resolve
the direct requirement’s version eagerly, which I don’t want to.
The implemented approach checks the version only after resolution, at
which point the distribution is already built anyway and the operation
is cheap.
These are the only cases where backtracking can happen. This approach
also accounts for VCS requirements relying on the same ensure function
to do cloning :/
We need to set the original link so the value is accessible in later
code, when we return the ireq backing the candidate. This is needed for
some parts of the post processing like PEP 610 support, which needs to
record the original, remote URL, not the potentially hit cache link.