1
1
Fork 0
mirror of https://github.com/pypa/pip synced 2023-12-13 21:30:23 +01:00
pip/src/pip/_internal/resolution/resolvelib/requirements.py

117 lines
3.3 KiB
Python
Raw Normal View History

from pip._vendor.packaging.utils import canonicalize_name
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
2020-03-25 13:25:23 +01:00
from .base import Requirement, format_name
if MYPY_CHECK_RUNNING:
2020-03-12 16:18:47 +01:00
from typing import Sequence
2020-03-12 16:18:47 +01:00
from pip._internal.req.req_install import InstallRequirement
from .base import Candidate
from .factory import Factory
2020-03-12 16:18:47 +01:00
class ExplicitRequirement(Requirement):
def __init__(self, candidate):
# type: (Candidate) -> None
self.candidate = candidate
def __repr__(self):
# type: () -> str
return "{class_name}({candidate!r})".format(
class_name=self.__class__.__name__,
candidate=self.candidate,
)
@property
def name(self):
# type: () -> str
2020-03-19 11:53:15 +01:00
# No need to canonicalise - the candidate did this
2020-03-12 16:18:47 +01:00
return self.candidate.name
def find_matches(self):
# type: () -> Sequence[Candidate]
return [self.candidate]
def is_satisfied_by(self, candidate):
# type: (Candidate) -> bool
2020-03-12 16:18:47 +01:00
return candidate == self.candidate
class NoMatchRequirement(Requirement):
"""A requirement that never matches anything.
2020-04-02 15:42:26 +02:00
Note: Similar to ExplicitRequirement, the caller should handle name
canonicalisation; this class does not perform it.
"""
def __init__(self, name):
# type: (str) -> None
2020-04-02 15:42:26 +02:00
self._name = name
def __repr__(self):
# type: () -> str
return "{class_name}(name={name!r})".format(
class_name=self.__class__.__name__,
name=self._name,
)
@property
def name(self):
# type: () -> str
return self._name
def find_matches(self):
# type: () -> Sequence[Candidate]
return []
def is_satisfied_by(self, candidate):
# type: (Candidate) -> bool
return False
2020-03-12 16:18:47 +01:00
class SpecifierRequirement(Requirement):
def __init__(self, ireq, factory):
# type: (InstallRequirement, Factory) -> None
2020-03-12 16:18:47 +01:00
assert ireq.link is None, "This is a link, not a specifier"
self._ireq = ireq
self._factory = factory
2020-03-25 13:25:23 +01:00
self.extras = ireq.req.extras
def __repr__(self):
# type: () -> str
return "{class_name}({requirement!r})".format(
class_name=self.__class__.__name__,
requirement=str(self._ireq.req),
)
@property
def name(self):
# type: () -> str
canonical_name = canonicalize_name(self._ireq.req.name)
2020-03-25 13:25:23 +01:00
return format_name(canonical_name, self.extras)
2020-03-12 16:18:47 +01:00
def find_matches(self):
# type: () -> Sequence[Candidate]
found = self._factory.finder.find_best_candidate(
project_name=self._ireq.req.name,
specifier=self._ireq.req.specifier,
hashes=self._ireq.hashes(trust_internet=False),
)
return [
self._factory.make_candidate_from_ican(
ican=ican,
extras=self.extras,
parent=self._ireq,
2020-03-12 16:18:47 +01:00
)
for ican in found.iter_applicable()
]
def is_satisfied_by(self, candidate):
# type: (Candidate) -> bool
2020-03-12 16:18:47 +01:00
assert candidate.name == self.name, \
2020-03-18 15:54:15 +01:00
"Internal issue: Candidate is not for this requirement " \
" {} vs {}".format(candidate.name, self.name)
return candidate.version in self._ireq.req.specifier