Skip to content

Commit

Permalink
Fix shell activation for zsh (#5795)
Browse files Browse the repository at this point in the history
# 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 <alecto.perez@voladynamics.com>
Co-authored-by: Bartosz Sokorski <b.sokorski@gmail.com>
  • Loading branch information
3 people authored Sep 6, 2022
1 parent 47255c4 commit 28d0175
Showing 1 changed file with 7 additions and 2 deletions.
9 changes: 7 additions & 2 deletions src/poetry/utils/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down

0 comments on commit 28d0175

Please sign in to comment.