Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/pip/_internal/req/__init__.py: 35%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

48 statements  

1from __future__ import annotations 

2 

3import collections 

4import logging 

5from collections.abc import Generator 

6from dataclasses import dataclass 

7 

8from pip._internal.cli.progress_bars import BarType, get_install_progress_renderer 

9from pip._internal.utils.logging import indent_log 

10 

11from .req_file import parse_requirements 

12from .req_install import InstallRequirement 

13from .req_set import RequirementSet 

14 

15__all__ = [ 

16 "RequirementSet", 

17 "InstallRequirement", 

18 "parse_requirements", 

19 "install_given_reqs", 

20] 

21 

22logger = logging.getLogger(__name__) 

23 

24 

25@dataclass(frozen=True) 

26class InstallationResult: 

27 name: str 

28 

29 

30def _validate_requirements( 

31 requirements: list[InstallRequirement], 

32) -> Generator[tuple[str, InstallRequirement], None, None]: 

33 for req in requirements: 

34 assert req.name, f"invalid to-be-installed requirement: {req}" 

35 yield req.name, req 

36 

37 

38def install_given_reqs( 

39 requirements: list[InstallRequirement], 

40 root: str | None, 

41 home: str | None, 

42 prefix: str | None, 

43 warn_script_location: bool, 

44 use_user_site: bool, 

45 pycompile: bool, 

46 progress_bar: BarType, 

47 script_executable: str | None = None, 

48) -> list[InstallationResult]: 

49 """ 

50 Install everything in the given list. 

51 

52 (to be called after having downloaded and unpacked the packages) 

53 """ 

54 to_install = collections.OrderedDict(_validate_requirements(requirements)) 

55 

56 if to_install: 

57 logger.info( 

58 "Installing collected packages: %s", 

59 ", ".join(to_install.keys()), 

60 ) 

61 

62 installed = [] 

63 

64 show_progress = logger.isEnabledFor(logging.INFO) and len(to_install) > 1 

65 

66 items = iter(to_install.values()) 

67 if show_progress: 

68 renderer = get_install_progress_renderer( 

69 bar_type=progress_bar, total=len(to_install) 

70 ) 

71 items = renderer(items) 

72 

73 with indent_log(): 

74 for requirement in items: 

75 req_name = requirement.name 

76 assert req_name is not None 

77 if requirement.should_reinstall: 

78 logger.info("Attempting uninstall: %s", req_name) 

79 with indent_log(): 

80 uninstalled_pathset = requirement.uninstall(auto_confirm=True) 

81 else: 

82 uninstalled_pathset = None 

83 

84 try: 

85 requirement.install( 

86 root=root, 

87 home=home, 

88 prefix=prefix, 

89 warn_script_location=warn_script_location, 

90 use_user_site=use_user_site, 

91 pycompile=pycompile, 

92 script_executable=script_executable, 

93 ) 

94 except Exception: 

95 # if install did not succeed, rollback previous uninstall 

96 if uninstalled_pathset and not requirement.install_succeeded: 

97 uninstalled_pathset.rollback() 

98 raise 

99 else: 

100 if uninstalled_pathset and requirement.install_succeeded: 

101 uninstalled_pathset.commit() 

102 

103 installed.append(InstallationResult(req_name)) 

104 

105 return installed