Created
March 12, 2020 14:08
-
-
Save pfmoore/128f2c74032efab97a2f83fa6dd3be31 to your computer and use it in GitHub Desktop.
Notes on the interface between Candidate and InstallRequirement
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Thoughts on the interface between a Candidate and an InstallRequirement. | |
The Candidate will hold a pip Link object as its "identifier" of the | |
distribution file/directory it represents. So it needs to be able to | |
say "Give me the (unique) InstallRequirement that's representing this | |
Link". I'd suggest that the interface has internally a Link->InstallRequirement | |
dictionary. | |
Creating the InstallRequirement needs a "parent" InstallRequirement from | |
which the options: | |
- editable | |
- markers | |
- use_pep517 | |
- isolated | |
- install_options | |
- global_options | |
- hash_options | |
- constraint | |
- extras (?) | |
will be copied. | |
We also need to be able to say "this has already been created with an | |
incompatible parent". Simple example - requirements.txt containing: | |
. | |
-e . | |
(first has a parent which is not editable, second has a parent which is | |
editable). | |
We need to create the InstallRequirement when we create the Candidate, as | |
that's the only time we have the parent (and the preparer) available. | |
So: | |
- find_matches creates a Candidate, providing a Link | |
- Candidate constructor calls "get me an InstallRequirement for this | |
Link, based on this Parent" | |
* If it gets back an InstallRequirement, save it for later. | |
* If it doesn't, that's because there's already an InstallRequirement | |
with an incompatible parent, and we can error. (The function that | |
gives back the link can raise the error directly, in fact). | |
The Candidate will only do one thing with the InstallRequirement - request | |
a pip._vendor.pkg_resources.Distribution from it. | |
Code for this is basically: | |
@property | |
def dist(self): | |
# type: () -> Distribution | |
if self._dist is None: | |
abstract_dist = self._preparer.prepare_linked_requirement( | |
self._install_requirement | |
) | |
self._dist = abstract_dist.get_pkg_resources_distribution() | |
# These should be "proper" errors, not just asserts, as they | |
# can result from user errors like a requirement "foo @ URL" | |
# when the project at URL has a name of "bar" in its metadata. | |
assert self._name is None or self._name == self._dist.project_name | |
assert self._version is None or self._version == self.dist.parsed_version | |
return self._dist | |
If the Candidate has no name, this will happen immediately, so we can | |
always assume candidates are named. But if the candidate has a name (e.g | |
`name @ URL`, or `foo >= 1.0`) then we'll lazily assume the given name is | |
correct until we need to prepare, hence the asserts in the above code. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment