You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Double parenthesis in activated venv generated by Python 3.12.10 #132361
/private/tmp via v3.1.3
❯ python3.12 -m venv venvsource venv/bin/activate/private/tmp via v3.12.10 (venv) via v3.1.3 took 10s
❯ python3.12 --versionPython 3.12.10/private/tmp via v3.12.10 (venv) via v3.1.3
I can reproduce this. I think this may be related to this diff, which was included in the 3.12 backport, but not in the main PR
if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then
_OLD_VIRTUAL_PS1="${PS1:-}"
- PS1=__VENV_PROMPT__"${PS1:-}"+ PS1="("__VENV_PROMPT__") ${PS1:-}"
export PS1
- VIRTUAL_ENV_PROMPT=__VENV_PROMPT__- export VIRTUAL_ENV_PROMPT
fi
For context, the generated activate script looks like this:
# [...]
VIRTUAL_ENV_PROMPT='(venv) 'export VIRTUAL_ENV_PROMPT
# unset PYTHONHOME if set# this will fail if PYTHONHOME is set to the empty string (which is bad anyway)# could use `if (set -u; : $PYTHONHOME) ;` in bashif [ -n"${PYTHONHOME:-}" ] ;then
_OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}"unset PYTHONHOME
fiif [ -z"${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ;then
_OLD_VIRTUAL_PS1="${PS1:-}"
PS1="("'(venv) '") ${PS1:-}"export PS1
fi# [...]
Suggest use either inject the environment name itself (e.g., venv312) into the prompt string,
and use only the shell script to format it, or if necessary (less optimal)
Use the VENV_ENV_PROMPT as is without adding additional parens & spaces
I can confirm that 3.13.5 at least has fixed this bug. It's such a simple but annoying one it's too bad it won't be backported to 3.11 & 3.12. There was some mention in the 'blame' section about quotes for avoiding injection so perhaps there is a security risk?
Just a +1 to say this is what I'd call out-of-character for Python at this point in its life? Introducing a bug into the last bugfix release of a version is disappointing. To compliment sandwich it, I suppose it says a lot that Python has gotten to the maturity where we can expect that things like this won't happen. But then they do happen. I can see that this won't get fixed, but with 3.13 being effectively a major version bump (due to cython major version incompatibility) and needing long runway, this—admittedly cosmetic—unfixable bug isn't up to the standard of professionalism I've come to expect from the hardworking maintainers of Python. Keep working hard, and know that I still believe in you all now more than I ever did before!
We don't use SemVer and every Python feature release is effectively a "major" bump due to removed deprecations.
If you'd like to help out, we have 2k open PRs that can benefit from review. Also the last ever 3.9 release is going out any day now before its EOL, so you're welcome to double check already merged PRs to that branch.
Activity
hugovk commentedon Apr 10, 2025
Please could you paste the terminal output?
This is what I get on macOS using iTerm:
i9wa4 commentedon Apr 10, 2025
I encountered this too.
brianschubert commentedon Apr 10, 2025
I can reproduce this. I think this may be related to this diff, which was included in the 3.12 backport, but not in the main PR
if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then _OLD_VIRTUAL_PS1="${PS1:-}" - PS1=__VENV_PROMPT__"${PS1:-}" + PS1="("__VENV_PROMPT__") ${PS1:-}" export PS1 - VIRTUAL_ENV_PROMPT=__VENV_PROMPT__ - export VIRTUAL_ENV_PROMPT fiFor context, the generated
activatescript looks like this:cc @vsajip
StanFromIreland commentedon Apr 15, 2025
This issue should be closed, it only affects 3.12 which no longer allows bugfixes.
hugovk commentedon Apr 16, 2025
Reproducible in 3.12:
But not 3.13:
StanFromIreland commentedon Apr 16, 2025
Very unfortunate, introduced just days before the deadline, and very visible too :-(
hugovk commentedon Apr 16, 2025
All the more reason to upgrade to Python 3.13, and get all the other bugfixes too 👍
gernophil commentedon May 22, 2025
Came here pretty late. Is this only a cosmetic bug or does it have any consequences?
hugovk commentedon May 22, 2025
Likely only cosmetic.
DellAnderson commentedon Jul 13, 2025
In case anyone wants to fix it themselves in a fork, here's what I think is going on:
The venv activate script generated by Python includes a redundant wrapping of parentheses and a trailing space in the PS1 prompt assignment.
In current versions (3.11, 3.12, not sure about 3.13), eg when creating a ~/venv312 environment:
the generated activate script includes the following:
VIRTUAL_ENV_PROMPT='(venv312) ' # note parens & trailing space.
...
Line 57
PS1="("VENV_PROMPT") ${PS1:-}" # note additional parens & interval space
This results in a prompt like: "((venv312) ) usersprompt$" prompt with double parentheses and an extra trailing space.
apparently because the script adds more parens & spaces in line 70:
https://github.com/python/cpython/blob/main/Lib/venv/scripts/common/activate
line 57
VIRTUAL_ENV_PROMPT=VENV_PROMPT
...
line 70
PS1="("VENV_PROMPT") ${PS1:-}" # Note added parens & trailing space around VENV_PROMPT
Suggested Fix:
Suggest use either inject the environment name itself (e.g., venv312) into the prompt string,
and use only the shell script to format it, or if necessary (less optimal)
Use the VENV_ENV_PROMPT as is without adding additional parens & spaces
#https://github.com/python/cpython/blob/main/Lib/venv/scripts/common/activate
line 57
VIRTUAL_ENV_PROMPT="(VENV_NAME)" #use only venv name, not a preformatted prompt
...
line 70
PS1="${VIRTUAL_ENV_PROMPT} ${PS1:-}" #remove extra parens & space here if unable to use VENV_NAME
This avoids duplication and makes the script easier to read, maintain or override.
The change should apply to:
May also need to remove formatting from template injection code here:
https://github.com/python/cpython/blob/main/Lib/venv/__init__.py (where
line 483 def replace_variables(self, text, context):
line 496 'VENV_NAME': context.env_name,
line 497 'VENV_PROMPT': context.prompt,
DellAnderson commentedon Jul 14, 2025
I can confirm that 3.13.5 at least has fixed this bug. It's such a simple but annoying one it's too bad it won't be backported to 3.11 & 3.12. There was some mention in the 'blame' section about quotes for avoiding injection so perhaps there is a security risk?
cdjameson commentedon Sep 19, 2025
Just a +1 to say this is what I'd call out-of-character for Python at this point in its life? Introducing a bug into the last bugfix release of a version is disappointing. To compliment sandwich it, I suppose it says a lot that Python has gotten to the maturity where we can expect that things like this won't happen. But then they do happen. I can see that this won't get fixed, but with 3.13 being effectively a major version bump (due to cython major version incompatibility) and needing long runway, this—admittedly cosmetic—unfixable bug isn't up to the standard of professionalism I've come to expect from the hardworking maintainers of Python. Keep working hard, and know that I still believe in you all now more than I ever did before!
hugovk commentedon Sep 20, 2025
We don't use SemVer and every Python feature release is effectively a "major" bump due to removed deprecations.
If you'd like to help out, we have 2k open PRs that can benefit from review. Also the last ever 3.9 release is going out any day now before its EOL, so you're welcome to double check already merged PRs to that branch.