|
27 | 27 | from .exceptions import ShellInitException, RunCommandException |
28 | 28 |
|
29 | 29 | NOTSET = object() |
| 30 | +MAX_PIP_INSTALL_ATTEMPTS = 2 |
30 | 31 |
|
31 | 32 |
|
32 | 33 | cli_style = Style([ |
@@ -235,19 +236,38 @@ class DebugInfo: |
235 | 236 | name2versions: Dict[str, Union[str, Dict[str, str]]] = {} |
236 | 237 |
|
237 | 238 |
|
238 | | -def pip_install(interpreter: str, requirements: str): |
239 | | - run = subprocess.check_call if logger.level <= logging.DEBUG else subprocess.check_output |
| 239 | +def install_pip(interpreter: str): |
| 240 | + get_pip_fpath: str = os.path.join(SHELL_LIB_DIR, "assets", "get-pip.py") |
| 241 | + if not os.path.exists(get_pip_fpath): |
| 242 | + msg = f"Required file for pip installation not found: {get_pip_fpath}" |
| 243 | + raise ShellInitException(msg) |
| 244 | + logger.info("Installing pip...") |
240 | 245 | try: |
241 | | - run( |
242 | | - [interpreter, "-m", "pip", "install", "-r", requirements], |
243 | | - stderr=subprocess.STDOUT, |
244 | | - env={} |
245 | | - ) |
| 246 | + subprocess.check_output([interpreter, get_pip_fpath], stderr=subprocess.PIPE) |
246 | 247 | except subprocess.CalledProcessError as e: |
247 | | - msg: str = "An error occurred while installing python dependencies" |
| 248 | + # TODO: test this failure case on purpose |
| 249 | + msg: str = "An error occurred while installing pip in the virtual environment" |
248 | 250 | raise ShellInitException(msg, stdout=e.stdout, stderr=e.stderr) |
249 | 251 |
|
250 | 252 |
|
| 253 | +def pip_install(interpreter: str, requirements: str): |
| 254 | + run = subprocess.check_call if logger.level <= logging.DEBUG else subprocess.check_output |
| 255 | + for attempt in range(MAX_PIP_INSTALL_ATTEMPTS): |
| 256 | + try: |
| 257 | + run( |
| 258 | + [interpreter, "-m", "pip", "install", "-r", requirements], |
| 259 | + stderr=subprocess.STDOUT, |
| 260 | + env={} |
| 261 | + ) |
| 262 | + break |
| 263 | + except subprocess.CalledProcessError as e: |
| 264 | + error = e.stdout.decode("utf-8", errors="replace") if e.stdout else "" |
| 265 | + if attempt == MAX_PIP_INSTALL_ATTEMPTS - 1 or "No module named pip" not in error: |
| 266 | + msg: str = "An error occurred while installing python dependencies" |
| 267 | + raise ShellInitException(msg, stdout=e.stdout, stderr=e.stderr) |
| 268 | + install_pip(interpreter) |
| 269 | + |
| 270 | + |
251 | 271 | def indent_block(s: str, indent_len: int = 4) -> str: |
252 | 272 | space: str = " " * indent_len |
253 | 273 | return space + f"\n{space}".join(s.splitlines() if s is not None else ["None"]) |
|
0 commit comments