Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/pip/_internal/req/req_set.py: 44%

50 statements  

« prev     ^ index     » next       coverage.py v7.4.3, created at 2024-02-26 06:33 +0000

1import logging 

2from collections import OrderedDict 

3from typing import Dict, List 

4 

5from pip._vendor.packaging.specifiers import LegacySpecifier 

6from pip._vendor.packaging.utils import canonicalize_name 

7from pip._vendor.packaging.version import LegacyVersion 

8 

9from pip._internal.req.req_install import InstallRequirement 

10from pip._internal.utils.deprecation import deprecated 

11 

12logger = logging.getLogger(__name__) 

13 

14 

15class RequirementSet: 

16 def __init__(self, check_supported_wheels: bool = True) -> None: 

17 """Create a RequirementSet.""" 

18 

19 self.requirements: Dict[str, InstallRequirement] = OrderedDict() 

20 self.check_supported_wheels = check_supported_wheels 

21 

22 self.unnamed_requirements: List[InstallRequirement] = [] 

23 

24 def __str__(self) -> str: 

25 requirements = sorted( 

26 (req for req in self.requirements.values() if not req.comes_from), 

27 key=lambda req: canonicalize_name(req.name or ""), 

28 ) 

29 return " ".join(str(req.req) for req in requirements) 

30 

31 def __repr__(self) -> str: 

32 requirements = sorted( 

33 self.requirements.values(), 

34 key=lambda req: canonicalize_name(req.name or ""), 

35 ) 

36 

37 format_string = "<{classname} object; {count} requirement(s): {reqs}>" 

38 return format_string.format( 

39 classname=self.__class__.__name__, 

40 count=len(requirements), 

41 reqs=", ".join(str(req.req) for req in requirements), 

42 ) 

43 

44 def add_unnamed_requirement(self, install_req: InstallRequirement) -> None: 

45 assert not install_req.name 

46 self.unnamed_requirements.append(install_req) 

47 

48 def add_named_requirement(self, install_req: InstallRequirement) -> None: 

49 assert install_req.name 

50 

51 project_name = canonicalize_name(install_req.name) 

52 self.requirements[project_name] = install_req 

53 

54 def has_requirement(self, name: str) -> bool: 

55 project_name = canonicalize_name(name) 

56 

57 return ( 

58 project_name in self.requirements 

59 and not self.requirements[project_name].constraint 

60 ) 

61 

62 def get_requirement(self, name: str) -> InstallRequirement: 

63 project_name = canonicalize_name(name) 

64 

65 if project_name in self.requirements: 

66 return self.requirements[project_name] 

67 

68 raise KeyError(f"No project with the name {name!r}") 

69 

70 @property 

71 def all_requirements(self) -> List[InstallRequirement]: 

72 return self.unnamed_requirements + list(self.requirements.values()) 

73 

74 @property 

75 def requirements_to_install(self) -> List[InstallRequirement]: 

76 """Return the list of requirements that need to be installed. 

77 

78 TODO remove this property together with the legacy resolver, since the new 

79 resolver only returns requirements that need to be installed. 

80 """ 

81 return [ 

82 install_req 

83 for install_req in self.all_requirements 

84 if not install_req.constraint and not install_req.satisfied_by 

85 ] 

86 

87 def warn_legacy_versions_and_specifiers(self) -> None: 

88 for req in self.requirements_to_install: 

89 version = req.get_dist().version 

90 if isinstance(version, LegacyVersion): 

91 deprecated( 

92 reason=( 

93 f"pip has selected the non standard version {version} " 

94 f"of {req}. In the future this version will be " 

95 f"ignored as it isn't standard compliant." 

96 ), 

97 replacement=( 

98 "set or update constraints to select another version " 

99 "or contact the package author to fix the version number" 

100 ), 

101 issue=12063, 

102 gone_in="24.1", 

103 ) 

104 for dep in req.get_dist().iter_dependencies(): 

105 if any(isinstance(spec, LegacySpecifier) for spec in dep.specifier): 

106 deprecated( 

107 reason=( 

108 f"pip has selected {req} {version} which has non " 

109 f"standard dependency specifier {dep}. " 

110 f"In the future this version of {req} will be " 

111 f"ignored as it isn't standard compliant." 

112 ), 

113 replacement=( 

114 "set or update constraints to select another version " 

115 "or contact the package author to fix the version number" 

116 ), 

117 issue=12063, 

118 gone_in="24.1", 

119 )