Skip to content

Conversation

@brunon
Copy link

@brunon brunon commented Nov 21, 2025

If the venv path is really long, uv will quote the python3 executable in the shebang and this breaks the LONG_SHEBANG_REGEX logic, which results in venv-pack2 not replacing the shebang line in the packed venv.

Steps to reproduce:

venv_path=/tmp/this/is/an/absurdly/long/path/to/test/the/shebang/line/at/some/point/it/gets/quoted/in/the/venv/binaries
mkdir -p $venv_path
python3 -m venv $venv_path
source $venv_path/bin/activate
python3 -m pip install --upgrade pip uv
uv pip install --compile memory_profiler
head -2 $venv_path/bin/mprof

Outputs this (note the executable path after exec is quoted):

#!/bin/sh
'''exec' '/private/tmp/this/is/an/absurdly/long/path/to/test/the/shebang/line/at/some/point/it/gets/quoted/in/the/venv/binaries/bin/python3' "$0" "$@"

This change ensures the optional quotes are supported and are not included as part of the command, ensuring it matches the prefix (venv path) and the shebang gets replaced correctly in the packed venv

If the venv path is really long, uv will quote the python3 executable in the shebang and this breaks the `LONG_SHEBANG_REGEX` logic, which results in venv-pack2 not replacing the shebang line in the packed venv.

Steps to reproduce:
```shell
venv_path=/tmp/this/is/an/absurdly/long/path/to/test/the/shebang/line/at/some/point/it/gets/quoted/in/the/venv/binaries
mkdir -p $venv_path
python3 -m venv $venv_path
source $venv_path/bin/activate
python3 -m pip install --upgrade pip uv
uv pip install --compile memory_profiler
head -2 $venv_path/bin/mprof
```

Outputs this (note the executable path after `exec` is quoted):
```shell
#!/bin/sh
'''exec' '/private/tmp/this/is/an/absurdly/long/path/to/test/the/shebang/line/at/some/point/it/gets/quoted/in/the/venv/binaries/bin/python3' "$0" "$@"
```
If the venv is created using a symlink (for example, on MacOS /tmp -> /private/tmp) then the 'prefix' (the venv path) will not match the executable in the shebang added by uv, as that will be the resolved path

Using `os.path.realpath()` ensures the two paths compared are fully resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant