| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- import logging
- from collections import OrderedDict
- from typing import Dict, List
- from pip._vendor.packaging.specifiers import LegacySpecifier
- from pip._vendor.packaging.utils import canonicalize_name
- from pip._vendor.packaging.version import LegacyVersion
- from pip._internal.req.req_install import InstallRequirement
- from pip._internal.utils.deprecation import deprecated
- logger = logging.getLogger(__name__)
- class RequirementSet:
- def __init__(self, check_supported_wheels: bool = True) -> None:
- """Create a RequirementSet."""
- self.requirements: Dict[str, InstallRequirement] = OrderedDict()
- self.check_supported_wheels = check_supported_wheels
- self.unnamed_requirements: List[InstallRequirement] = []
- def __str__(self) -> str:
- requirements = sorted(
- (req for req in self.requirements.values() if not req.comes_from),
- key=lambda req: canonicalize_name(req.name or ""),
- )
- return " ".join(str(req.req) for req in requirements)
- def __repr__(self) -> str:
- requirements = sorted(
- self.requirements.values(),
- key=lambda req: canonicalize_name(req.name or ""),
- )
- format_string = "<{classname} object; {count} requirement(s): {reqs}>"
- return format_string.format(
- classname=self.__class__.__name__,
- count=len(requirements),
- reqs=", ".join(str(req.req) for req in requirements),
- )
- def add_unnamed_requirement(self, install_req: InstallRequirement) -> None:
- assert not install_req.name
- self.unnamed_requirements.append(install_req)
- def add_named_requirement(self, install_req: InstallRequirement) -> None:
- assert install_req.name
- project_name = canonicalize_name(install_req.name)
- self.requirements[project_name] = install_req
- def has_requirement(self, name: str) -> bool:
- project_name = canonicalize_name(name)
- return (
- project_name in self.requirements
- and not self.requirements[project_name].constraint
- )
- def get_requirement(self, name: str) -> InstallRequirement:
- project_name = canonicalize_name(name)
- if project_name in self.requirements:
- return self.requirements[project_name]
- raise KeyError(f"No project with the name {name!r}")
- @property
- def all_requirements(self) -> List[InstallRequirement]:
- return self.unnamed_requirements + list(self.requirements.values())
- @property
- def requirements_to_install(self) -> List[InstallRequirement]:
- """Return the list of requirements that need to be installed.
- TODO remove this property together with the legacy resolver, since the new
- resolver only returns requirements that need to be installed.
- """
- return [
- install_req
- for install_req in self.all_requirements
- if not install_req.constraint and not install_req.satisfied_by
- ]
- def warn_legacy_versions_and_specifiers(self) -> None:
- for req in self.requirements_to_install:
- version = req.get_dist().version
- if isinstance(version, LegacyVersion):
- deprecated(
- reason=(
- f"pip has selected the non standard version {version} "
- f"of {req}. In the future this version will be "
- f"ignored as it isn't standard compliant."
- ),
- replacement=(
- "set or update constraints to select another version "
- "or contact the package author to fix the version number"
- ),
- issue=12063,
- gone_in="24.1",
- )
- for dep in req.get_dist().iter_dependencies():
- if any(isinstance(spec, LegacySpecifier) for spec in dep.specifier):
- deprecated(
- reason=(
- f"pip has selected {req} {version} which has non "
- f"standard dependency specifier {dep}. "
- f"In the future this version of {req} will be "
- f"ignored as it isn't standard compliant."
- ),
- replacement=(
- "set or update constraints to select another version "
- "or contact the package author to fix the version number"
- ),
- issue=12063,
- gone_in="24.1",
- )
|