Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/pip/_internal/exceptions/build.py: 47%

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

60 statements  

1"""Build environment related pip exceptions.""" 

2 

3from __future__ import annotations 

4 

5import os 

6import sys 

7import traceback 

8from collections.abc import Iterable 

9from typing import TYPE_CHECKING 

10 

11from pip._vendor.rich.markup import escape 

12from pip._vendor.rich.text import Text 

13 

14from pip._internal.exceptions._base import ( 

15 DiagnosticPipError, 

16 InstallationError, 

17 PipError, 

18) 

19 

20if TYPE_CHECKING: 

21 from pip._internal.req.req_install import InstallRequirement 

22 

23 

24class BuildDependencyInstallError(DiagnosticPipError): 

25 """Raised when build dependencies cannot be installed.""" 

26 

27 reference = "failed-build-dependency-install" 

28 

29 def __init__( 

30 self, 

31 req: InstallRequirement | None, 

32 build_reqs: Iterable[str], 

33 *, 

34 cause: Exception, 

35 log_lines: list[str] | None, 

36 ) -> None: 

37 if isinstance(cause, PipError): 

38 note = "This is likely not a problem with pip." 

39 else: 

40 note = ( 

41 "pip crashed unexpectedly. Please file an issue on pip's issue " 

42 "tracker: https://github.com/pypa/pip/issues/new" 

43 ) 

44 

45 if log_lines is None: 

46 # No logs are available, they must have been printed earlier. 

47 context = Text("See above for more details.") 

48 else: 

49 if isinstance(cause, PipError): 

50 log_lines.append(f"ERROR: {cause}") 

51 else: 

52 # Split rendered error into real lines without trailing newlines. 

53 log_lines.extend( 

54 "".join(traceback.format_exception(cause)).splitlines() 

55 ) 

56 

57 context = Text.assemble( 

58 f"Installing {' '.join(build_reqs)}\n", 

59 (f"[{len(log_lines)} lines of output]\n", "red"), 

60 "\n".join(log_lines), 

61 ("\n[end of output]", "red"), 

62 ) 

63 

64 message = Text("Cannot install build dependencies", "green") 

65 if req: 

66 message += Text(f" for {req}") 

67 super().__init__( 

68 message=message, context=context, hint_stmt=None, note_stmt=note 

69 ) 

70 

71 

72class VenvImportError(DiagnosticPipError): 

73 """Raised when 'venv' can't be imported.""" 

74 

75 reference = "venv-import-error" 

76 

77 def __init__(self) -> None: 

78 if sys.platform != "linux": 

79 hint_stmt = None 

80 else: 

81 hint_stmt = ( 

82 "If this is an OS-provided Python, it's likely that your OS " 

83 "package maintainers have split Python's standard library across " 

84 "multiple OS packages." 

85 ) 

86 super().__init__( 

87 message="Cannot import the 'venv' module of the Python standard library", 

88 context=( 

89 "This is a symptom of a broken/modified Python, which cannot be used " 

90 "with pip." 

91 ), 

92 note_stmt="This is an issue with the Python installation itself, not pip.", 

93 hint_stmt=hint_stmt, 

94 ) 

95 

96 

97class VenvCreationError(DiagnosticPipError): 

98 """Raised when a virtual environment can't be created.""" 

99 

100 reference = "venv-creation-error" 

101 

102 def __init__(self, context: str) -> None: 

103 if os.name == "nt": 

104 hint = "This may be caused by running antivirus software." 

105 else: 

106 hint = None 

107 super().__init__( 

108 message="Cannot create a virtual environment", 

109 context=Text(context), 

110 hint_stmt=hint, 

111 ) 

112 

113 

114class InstallationSubprocessError(DiagnosticPipError, InstallationError): 

115 """A subprocess call failed.""" 

116 

117 reference = "subprocess-exited-with-error" 

118 

119 def __init__( 

120 self, 

121 *, 

122 command_description: str, 

123 exit_code: int, 

124 output_lines: list[str] | None, 

125 ) -> None: 

126 if output_lines is None: 

127 output_prompt = Text("No available output.") 

128 else: 

129 output_prompt = ( 

130 Text.from_markup(f"[red][{len(output_lines)} lines of output][/]\n") 

131 + Text("".join(output_lines)) 

132 + Text.from_markup(R"[red]\[end of output][/]") 

133 ) 

134 

135 super().__init__( 

136 message=( 

137 f"[green]{escape(command_description)}[/] did not run successfully.\n" 

138 f"exit code: {exit_code}" 

139 ), 

140 context=output_prompt, 

141 hint_stmt=None, 

142 note_stmt=( 

143 "This error originates from a subprocess, and is likely not a " 

144 "problem with pip." 

145 ), 

146 ) 

147 

148 self.command_description = command_description 

149 self.exit_code = exit_code 

150 

151 def __str__(self) -> str: 

152 return f"{self.command_description} exited with {self.exit_code}" 

153 

154 

155class BackendUnavailableError(InstallationSubprocessError): 

156 """The build backend could not be loaded.""" 

157 

158 reference = "backend-unavailable" 

159 

160 def __init__( 

161 self, *, hook_name: str, backend_name: str, backend_error: str 

162 ) -> None: 

163 DiagnosticPipError.__init__( 

164 self, 

165 message=f"Cannot import build backend {escape(backend_name)!r}.", 

166 context=backend_error, 

167 hint_stmt=None, 

168 note_stmt="This is likely not a problem with pip.", 

169 ) 

170 self.command_description = f"Calling build backend hook {hook_name}" 

171 

172 def __str__(self) -> str: 

173 return str(self.message)