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.
This mirrors the behavior in the legacy resolver. In the future we may
want to backtrack in this situation instead, but I haven't found a clean
way to do this. We may need to introduce an "empty" requirement class.
The `PackageFinder.target_python` interface is also not the most clean.
Maybe we should expose the target Python object instead. Not sure yet.
This specialized class is able to carry more context information than
the previous implementation (which reuses ExplicitRequirement). Error
reports can thus provide better messages by introspecting.
This rewrites how a SpecifierRequirement generates candidates, so it
* Always return an AlreadyInstalledCandidate (as long as the version
satisfies the specifier), even if PackageFinder does not return a
candidate for the same version.
* Always put the AlreadyInstalledCandidate last, so it's preferred over
LinkCandidate, preventing version changes if possible.
The candidate creation logic is further moved into the factory. The
factory would use pkg_resources.get_distribution() to find a matching
distribution for a givan InstallationCandidate. If found, the Candidate
would be created based on that found distribution, instead of the link.
--ignore-installed is implemented as to always use the link to create
candidates, even if an installed distribution is found.