From dc7b2eef913d7badf3a096d88cfc79e90d409a94 Mon Sep 17 00:00:00 2001 From: guahki Date: Thu, 25 Jan 2024 23:00:49 +0100 Subject: [PATCH] Fix path resolution for python executables looked up in PATH on windows by moving the whole os.path.realpath logic introduced in #1168 to pipx.util:get_venv_paths --- changelog.d/1205.bugfix.md | 1 + src/pipx/shared_libs.py | 2 ++ src/pipx/util.py | 12 ++++-------- 3 files changed, 7 insertions(+), 8 deletions(-) create mode 100644 changelog.d/1205.bugfix.md diff --git a/changelog.d/1205.bugfix.md b/changelog.d/1205.bugfix.md new file mode 100644 index 0000000000..9f0f8ebe3c --- /dev/null +++ b/changelog.d/1205.bugfix.md @@ -0,0 +1 @@ +Fix path resolution for python executables looked up in PATH on windows. diff --git a/src/pipx/shared_libs.py b/src/pipx/shared_libs.py index eaa4920970..51a9bf67fc 100644 --- a/src/pipx/shared_libs.py +++ b/src/pipx/shared_libs.py @@ -47,6 +47,8 @@ def create(self, verbose: bool = False) -> None: [DEFAULT_PYTHON, "-m", "venv", "--clear", self.root], run_dir=str(self.root) ) subprocess_post_check(create_process) + # Recompute these paths, as they might resolve differently now, see comment in get_venv_paths + self.bin_path, self.python_path, self.man_path = get_venv_paths(self.root) # ignore installed packages to ensure no unexpected patches from the OS vendor # are used diff --git a/src/pipx/util.py b/src/pipx/util.py index 8a498e853a..891bf26d60 100644 --- a/src/pipx/util.py +++ b/src/pipx/util.py @@ -108,6 +108,10 @@ def run_pypackage_bin(bin_path: Path, args: List[str]) -> NoReturn: if WINDOWS: def get_venv_paths(root: Path) -> Tuple[Path, Path, Path]: + # Make sure to use the real root path. This matters especially on Windows when using the packaged app + # (Microsoft Store) version of Python, which uses path redirection for sandboxing. + # See https://github.com/pypa/pipx/issues/1164 + root = root.resolve() bin_path = root / "Scripts" if not MINGW else root / "bin" python_path = bin_path / "python.exe" man_path = root / "share" / "man" @@ -171,14 +175,6 @@ def run_subprocess( os.makedirs(run_dir, exist_ok=True) # windows cannot take Path objects, only strings cmd_str_list = [str(c) for c in cmd] - # Make sure to call the binary using its real path. This matters especially on Windows when using the packaged app - # (Microsoft Store) version of Python, which uses path redirection for sandboxing. If the path to the executable is - # redirected, the executable can get confused as to which directory it's being run from, leading to problems. - # See https://github.com/pypa/pipx/issues/1164 - # Conversely, if the binary is a symlink, then we should NOT use the real path, as Python expects to receive the - # symlink in argv[0] so that it can locate the venv. - if not os.path.islink(cmd_str_list[0]) and WINDOWS: - cmd_str_list[0] = os.path.realpath(cmd_str_list[0]) # TODO: Switch to using `-P` / PYTHONSAFEPATH instead of running in # separate directory in Python 3.11