Skip to content

Commit fb07173

Browse files
fix: streamline pip installation process in virtual environments
1 parent 875e595 commit fb07173

File tree

2 files changed

+30
-19
lines changed

2 files changed

+30
-19
lines changed

lib/dt_shell/environments.py

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from .constants import SHELL_LIB_DIR, SHELL_REQUIREMENTS_LIST, DTShellConstants
1515
from .database.utils import InstalledDependenciesDatabase
1616
from .logging import dts_print
17-
from .utils import pip_install, replace_spaces, print_debug_info, pretty_json
17+
from .utils import install_pip, pip_install, replace_spaces, print_debug_info, pretty_json
1818

1919

2020
class ShellCommandEnvironmentAbs(metaclass=ABCMeta):
@@ -110,16 +110,7 @@ def execute(self, shell, _: List[str]):
110110
with_pip=False,
111111
prompt="dts"
112112
)
113-
# install pip
114-
get_pip_fpath: str = os.path.join(SHELL_LIB_DIR, "assets", "get-pip.py")
115-
assert os.path.exists(get_pip_fpath)
116-
logger.info(f"Installing pip...")
117-
try:
118-
subprocess.check_output([interpreter_fpath, get_pip_fpath], stderr=subprocess.PIPE)
119-
except subprocess.CalledProcessError as e:
120-
# TODO: test this failure case on purpose
121-
msg: str = "An error occurred while installing pip in the virtual environment"
122-
raise ShellInitException(msg, stdout=e.stdout, stderr=e.stderr)
113+
install_pip(interpreter_fpath)
123114

124115
# install dependencies
125116
cache: InstalledDependenciesDatabase = InstalledDependenciesDatabase.load(shell.profile)

lib/dt_shell/utils.py

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from .exceptions import ShellInitException, RunCommandException
2828

2929
NOTSET = object()
30+
MAX_PIP_INSTALL_ATTEMPTS = 2
3031

3132

3233
cli_style = Style([
@@ -235,19 +236,38 @@ class DebugInfo:
235236
name2versions: Dict[str, Union[str, Dict[str, str]]] = {}
236237

237238

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...")
240245
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)
246247
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"
248250
raise ShellInitException(msg, stdout=e.stdout, stderr=e.stderr)
249251

250252

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+
251271
def indent_block(s: str, indent_len: int = 4) -> str:
252272
space: str = " " * indent_len
253273
return space + f"\n{space}".join(s.splitlines() if s is not None else ["None"])

0 commit comments

Comments
 (0)