From 28d0175dc599dca3d582c2c110a6ea6fe39049c7 Mon Sep 17 00:00:00 2001 From: Alecto Irene Perez Date: Tue, 6 Sep 2022 17:47:13 -0400 Subject: [PATCH] Fix shell activation for zsh (#5795) # Fix Shell Activation For ZSH This PR resolves an issue wherein poetry will clear the `PATH` on zsh. The activation script contains a number of if statements of the following form: ```bash # ... if ! [ -z "${_OLD_VIRTUAL_PATH:+_}" ] ; then PATH="$_OLD_VIRTUAL_PATH" export PATH unset _OLD_VIRTUAL_PATH fi ``` These constructs are valid in bash, although zsh fails to negate the conditional except when placed in emulation mode: ```zsh # Causes PATH to be cleared, leading to other issues . /home/alecto/.cache/pypoetry/virtualenvs/poetry-E-aAiPjf-py3.10/bin/activate ``` When bash is used as an emulator to source the script, it functions correctly: ```zsh # Functions correctly emulate bash -c '. /home/alecto/.cache/pypoetry/virtualenvs/poetry-E-aAiPjf-py3.10/bin/activate' ``` It's important to note that this doesn't place the *entire* shell into bash emulation mode; only the activate script is sourced as bash. Any guidance on what tests should be added for this PR would be appreciated. Co-authored-by: Alecto Irene Perez Co-authored-by: Bartosz Sokorski --- src/poetry/utils/shell.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/poetry/utils/shell.py b/src/poetry/utils/shell.py index 431879a52b4..45d002fec85 100644 --- a/src/poetry/utils/shell.py +++ b/src/poetry/utils/shell.py @@ -95,8 +95,13 @@ def activate(self, env: VirtualEnv) -> int | None: if self._name in ["zsh", "nu"]: c.setecho(False) - - c.sendline(f"{self._get_source_command()} {shlex.quote(str(activate_path))}") + if self._name == "zsh": + # Under ZSH the source command should be invoked in zsh's bash emulator + c.sendline(f"emulate bash -c '. {shlex.quote(str(activate_path))}'") + else: + c.sendline( + f"{self._get_source_command()} {shlex.quote(str(activate_path))}" + ) def resize(sig: Any, data: Any) -> None: terminal = shutil.get_terminal_size()