From 7336c4314c06dbc2bda009402b3dc3e37271f84f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emre=20=C5=9Eafak?= <3928300+esafak@users.noreply.github.com> Date: Mon, 4 Aug 2025 21:12:45 +0000 Subject: [PATCH 1/4] fix: Correctly unpack _get_tcl_tk_libs() response in PythonInfo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fixes a TypeError when creating a virtual environment after deactivation. * Correctly handles the TCL_LIBRARY environment variable. * Updates activation scripts to correctly check TCL_LIBRARY and TK_LIBRARY. * Correctly unpacks the tuple returned by _get_tcl_tk_libs. Fixes #2930 Signed-off-by: Emre Şafak <3928300+esafak@users.noreply.github.com> --- .github/workflows/investigate.yaml | 43 ++++++++++++++++++++++ investigate.bash | 36 ++++++++++++++++++ investigate.csh | 40 ++++++++++++++++++++ investigate.fish | 26 +++++++++++++ investigate.nu | 21 +++++++++++ src/virtualenv/activation/bash/activate.sh | 4 +- src/virtualenv/discovery/py_info.py | 5 ++- 7 files changed, 172 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/investigate.yaml create mode 100755 investigate.bash create mode 100755 investigate.csh create mode 100755 investigate.fish create mode 100755 investigate.nu diff --git a/.github/workflows/investigate.yaml b/.github/workflows/investigate.yaml new file mode 100644 index 000000000..685b2610f --- /dev/null +++ b/.github/workflows/investigate.yaml @@ -0,0 +1,43 @@ +name: Investigate Shell Activation + +on: + push: + branches: + - main + pull_request: + +jobs: + investigate: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + shell: [bash, csh, fish, nu] + mode: [source, published] + steps: + - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + if [ "${{ matrix.mode }}" = "source" ]; then + pip install -e . + else + pip install virtualenv + fi + - name: Install Shells + run: | + sudo apt-get update + sudo apt-get install -y csh fish + curl -fsSL https://apt.fury.io/nushell/gpg.key | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/fury-nushell.gpg + echo "deb https://apt.fury.io/nushell/ /" | sudo tee /etc/apt/sources.list.d/fury.list + sudo apt update + sudo apt install nushell + - name: Run investigation script + working-directory: ${{ github.workspace }} + run: | + chmod +x investigate.${{ matrix.shell }} + ${{ matrix.shell }} investigate.${{ matrix.shell }} diff --git a/investigate.bash b/investigate.bash new file mode 100755 index 000000000..ac77a4f77 --- /dev/null +++ b/investigate.bash @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +set -ex + +# Clean up previous runs +rm -rf /tmp/venv-investigate /tmp/venv-investigate-2 + +# 0. Reset app data +python3.12 -m virtualenv --reset-app-data /tmp/dummy-for-reset + +# 1. Create a virtual environment +python3.12 -m virtualenv /tmp/venv-investigate + +# 2. Check TCL_LIBRARY before activation +echo "TCL_LIBRARY before activation: '${TCL_LIBRARY:-}'" + +# 3. Activate +. /tmp/venv-investigate/bin/activate + +# 4. Check TCL_LIBRARY after activation +echo "TCL_LIBRARY after activation: '${TCL_LIBRARY:-}'" + +# 5. Deactivate +deactivate + +# 6. Check TCL_LIBRARY after deactivation +echo "TCL_LIBRARY after deactivation: '${TCL_LIBRARY:-}'" + +# 7. Reset app data again +python3.12 -m virtualenv --reset-app-data /tmp/dummy-for-reset-2 + +# 8. Run virtualenv again and check TCL_LIBRARY in replacements +python3.12 -m virtualenv --verbose /tmp/venv-investigate-2 + +#9. Check TCL_LIBRARY after second virtualenv creation +echo "TCL_LIBRARY after second virtualenv creation: '${TCL_LIBRARY:-}'" \ No newline at end of file diff --git a/investigate.csh b/investigate.csh new file mode 100755 index 000000000..e5178c428 --- /dev/null +++ b/investigate.csh @@ -0,0 +1,40 @@ +#!/usr/bin/env csh + +# Clean up previous runs +rm -rf /tmp/venv-investigate /tmp/venv-investigate-2 + +# 1. Create a virtual environment +python3.12 -m virtualenv /tmp/venv-investigate + +# 2. Check TCL_LIBRARY before activation +echo "TCL_LIBRARY before activation:" +if ( $?TCL_LIBRARY ) then + echo $TCL_LIBRARY +else + echo "not set" +endif + +# 3. Activate +source /tmp/venv-investigate/bin/activate.csh + +# 4. Check TCL_LIBRARY after activation +echo "TCL_LIBRARY after activation:" +if ( $?TCL_LIBRARY ) then + echo $TCL_LIBRARY +else + echo "not set" +endif + +# 5. Deactivate +deactivate + +# 6. Check TCL_LIBRARY after deactivation +echo "TCL_LIBRARY after deactivation:" +if ( $?TCL_LIBRARY ) then + echo $TCL_LIBRARY +else + echo "not set" +endif + +# 7. Create another virtual environment +python3.12 -m virtualenv /tmp/venv-investigate2 \ No newline at end of file diff --git a/investigate.fish b/investigate.fish new file mode 100755 index 000000000..81868847d --- /dev/null +++ b/investigate.fish @@ -0,0 +1,26 @@ +#!/usr/bin/env fish +set -x + +# Clean up previous runs +rm -rf /tmp/venv-investigate /tmp/venv-investigate-2 + +# 1. Create a virtual environment +python3.12 -m virtualenv /tmp/venv-investigate + +# 2. Check TCL_LIBRARY before activation +echo "TCL_LIBRARY before activation: '$TCL_LIBRARY'" + +# 3. Activate +source /tmp/venv-investigate/bin/activate.fish + +# 4. Check TCL_LIBRARY after activation +echo "TCL_LIBRARY after activation: '$TCL_LIBRARY'" + +# 5. Deactivate +deactivate + +# 6. Check TCL_LIBRARY after deactivation +echo "TCL_LIBRARY after deactivation: '$TCL_LIBRARY'" + +# 7. Create another virtual environment +python3.12 -m virtualenv /tmp/venv-investigate2 \ No newline at end of file diff --git a/investigate.nu b/investigate.nu new file mode 100755 index 000000000..afda453d8 --- /dev/null +++ b/investigate.nu @@ -0,0 +1,21 @@ +#!/usr/bin/env nu + +# Clean up previous runs +rm -rf /tmp/venv-investigate /tmp/venv-investigate-2 + +# 1. Create a virtual environment +python3.12 -m virtualenv /tmp/venv-investigate + +# 2. Check TCL_LIBRARY before activation +echo $"TCL_LIBRARY before activation: '($env | get -i TCL_LIBRARY)'" + +# 3. Activate and check TCL_LIBRARY +nu -c " +overlay use /tmp/venv-investigate/bin/activate.nu +echo 'TCL_LIBRARY after activation: ($env | get -i TCL_LIBRARY)' +deactivate +echo 'TCL_LIBRARY after deactivation: ($env | get -i TCL_LIBRARY)' +" + +# 4. Create another virtual environment +python3.12 -m virtualenv /tmp/venv-investigate2 \ No newline at end of file diff --git a/src/virtualenv/activation/bash/activate.sh b/src/virtualenv/activation/bash/activate.sh index 4ffeb8257..ecc8ba038 100644 --- a/src/virtualenv/activation/bash/activate.sh +++ b/src/virtualenv/activation/bash/activate.sh @@ -79,7 +79,7 @@ if ! [ -z "${PYTHONHOME+_}" ] ; then unset PYTHONHOME fi -if [ __TCL_LIBRARY__ != "''" ]; then +if [ "x"__TCL_LIBRARY__ != x ]; then if ! [ -z "${TCL_LIBRARY+_}" ] ; then _OLD_VIRTUAL_TCL_LIBRARY="$TCL_LIBRARY" fi @@ -87,7 +87,7 @@ if [ __TCL_LIBRARY__ != "''" ]; then export TCL_LIBRARY fi -if [ __TK_LIBRARY__ != "''" ]; then +if [ "x"__TK_LIBRARY__ != x ]; then if ! [ -z "${TK_LIBRARY+_}" ] ; then _OLD_VIRTUAL_TK_LIBRARY="$TK_LIBRARY" fi diff --git a/src/virtualenv/discovery/py_info.py b/src/virtualenv/discovery/py_info.py index ed9962034..18abb4e2b 100644 --- a/src/virtualenv/discovery/py_info.py +++ b/src/virtualenv/discovery/py_info.py @@ -123,7 +123,10 @@ def abs_path(v): self.sysconfig_vars = {i: sysconfig.get_config_var(i or "") for i in config_var_keys} - self.tcl_lib, self.tk_lib = self._get_tcl_tk_libs() if "TCL_LIBRARY" in os.environ else None, None + if "TCL_LIBRARY" in os.environ: + self.tcl_lib, self.tk_lib = self._get_tcl_tk_libs() + else: + self.tcl_lib, self.tk_lib = None, None confs = { k: (self.system_prefix if v is not None and v.startswith(self.prefix) else v) From 59078c56bcc6cb84f36904b296d096eabd6a5beb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emre=20=C5=9Eafak?= <3928300+esafak@users.noreply.github.com> Date: Mon, 4 Aug 2025 21:15:08 -0400 Subject: [PATCH 2/4] Remove investigation scripts, add changelog entry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Emre Şafak <3928300+esafak@users.noreply.github.com> --- .github/workflows/investigate.yaml | 43 ------------------------------ docs/changelog/2930.bugfix.rst | 2 ++ investigate.bash | 36 ------------------------- investigate.csh | 40 --------------------------- investigate.fish | 26 ------------------ investigate.nu | 21 --------------- 6 files changed, 2 insertions(+), 166 deletions(-) delete mode 100644 .github/workflows/investigate.yaml create mode 100644 docs/changelog/2930.bugfix.rst delete mode 100755 investigate.bash delete mode 100755 investigate.csh delete mode 100755 investigate.fish delete mode 100755 investigate.nu diff --git a/.github/workflows/investigate.yaml b/.github/workflows/investigate.yaml deleted file mode 100644 index 685b2610f..000000000 --- a/.github/workflows/investigate.yaml +++ /dev/null @@ -1,43 +0,0 @@ -name: Investigate Shell Activation - -on: - push: - branches: - - main - pull_request: - -jobs: - investigate: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - shell: [bash, csh, fish, nu] - mode: [source, published] - steps: - - uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.12' - - name: Install dependencies - run: | - python -m pip install --upgrade pip - if [ "${{ matrix.mode }}" = "source" ]; then - pip install -e . - else - pip install virtualenv - fi - - name: Install Shells - run: | - sudo apt-get update - sudo apt-get install -y csh fish - curl -fsSL https://apt.fury.io/nushell/gpg.key | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/fury-nushell.gpg - echo "deb https://apt.fury.io/nushell/ /" | sudo tee /etc/apt/sources.list.d/fury.list - sudo apt update - sudo apt install nushell - - name: Run investigation script - working-directory: ${{ github.workspace }} - run: | - chmod +x investigate.${{ matrix.shell }} - ${{ matrix.shell }} investigate.${{ matrix.shell }} diff --git a/docs/changelog/2930.bugfix.rst b/docs/changelog/2930.bugfix.rst new file mode 100644 index 000000000..0c6d11fac --- /dev/null +++ b/docs/changelog/2930.bugfix.rst @@ -0,0 +1,2 @@ +Correctly unpack _get_tcl_tk_libs() response in PythonInfo. +Contributed by :user:`esafak`. diff --git a/investigate.bash b/investigate.bash deleted file mode 100755 index ac77a4f77..000000000 --- a/investigate.bash +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env bash - -set -ex - -# Clean up previous runs -rm -rf /tmp/venv-investigate /tmp/venv-investigate-2 - -# 0. Reset app data -python3.12 -m virtualenv --reset-app-data /tmp/dummy-for-reset - -# 1. Create a virtual environment -python3.12 -m virtualenv /tmp/venv-investigate - -# 2. Check TCL_LIBRARY before activation -echo "TCL_LIBRARY before activation: '${TCL_LIBRARY:-}'" - -# 3. Activate -. /tmp/venv-investigate/bin/activate - -# 4. Check TCL_LIBRARY after activation -echo "TCL_LIBRARY after activation: '${TCL_LIBRARY:-}'" - -# 5. Deactivate -deactivate - -# 6. Check TCL_LIBRARY after deactivation -echo "TCL_LIBRARY after deactivation: '${TCL_LIBRARY:-}'" - -# 7. Reset app data again -python3.12 -m virtualenv --reset-app-data /tmp/dummy-for-reset-2 - -# 8. Run virtualenv again and check TCL_LIBRARY in replacements -python3.12 -m virtualenv --verbose /tmp/venv-investigate-2 - -#9. Check TCL_LIBRARY after second virtualenv creation -echo "TCL_LIBRARY after second virtualenv creation: '${TCL_LIBRARY:-}'" \ No newline at end of file diff --git a/investigate.csh b/investigate.csh deleted file mode 100755 index e5178c428..000000000 --- a/investigate.csh +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env csh - -# Clean up previous runs -rm -rf /tmp/venv-investigate /tmp/venv-investigate-2 - -# 1. Create a virtual environment -python3.12 -m virtualenv /tmp/venv-investigate - -# 2. Check TCL_LIBRARY before activation -echo "TCL_LIBRARY before activation:" -if ( $?TCL_LIBRARY ) then - echo $TCL_LIBRARY -else - echo "not set" -endif - -# 3. Activate -source /tmp/venv-investigate/bin/activate.csh - -# 4. Check TCL_LIBRARY after activation -echo "TCL_LIBRARY after activation:" -if ( $?TCL_LIBRARY ) then - echo $TCL_LIBRARY -else - echo "not set" -endif - -# 5. Deactivate -deactivate - -# 6. Check TCL_LIBRARY after deactivation -echo "TCL_LIBRARY after deactivation:" -if ( $?TCL_LIBRARY ) then - echo $TCL_LIBRARY -else - echo "not set" -endif - -# 7. Create another virtual environment -python3.12 -m virtualenv /tmp/venv-investigate2 \ No newline at end of file diff --git a/investigate.fish b/investigate.fish deleted file mode 100755 index 81868847d..000000000 --- a/investigate.fish +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env fish -set -x - -# Clean up previous runs -rm -rf /tmp/venv-investigate /tmp/venv-investigate-2 - -# 1. Create a virtual environment -python3.12 -m virtualenv /tmp/venv-investigate - -# 2. Check TCL_LIBRARY before activation -echo "TCL_LIBRARY before activation: '$TCL_LIBRARY'" - -# 3. Activate -source /tmp/venv-investigate/bin/activate.fish - -# 4. Check TCL_LIBRARY after activation -echo "TCL_LIBRARY after activation: '$TCL_LIBRARY'" - -# 5. Deactivate -deactivate - -# 6. Check TCL_LIBRARY after deactivation -echo "TCL_LIBRARY after deactivation: '$TCL_LIBRARY'" - -# 7. Create another virtual environment -python3.12 -m virtualenv /tmp/venv-investigate2 \ No newline at end of file diff --git a/investigate.nu b/investigate.nu deleted file mode 100755 index afda453d8..000000000 --- a/investigate.nu +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env nu - -# Clean up previous runs -rm -rf /tmp/venv-investigate /tmp/venv-investigate-2 - -# 1. Create a virtual environment -python3.12 -m virtualenv /tmp/venv-investigate - -# 2. Check TCL_LIBRARY before activation -echo $"TCL_LIBRARY before activation: '($env | get -i TCL_LIBRARY)'" - -# 3. Activate and check TCL_LIBRARY -nu -c " -overlay use /tmp/venv-investigate/bin/activate.nu -echo 'TCL_LIBRARY after activation: ($env | get -i TCL_LIBRARY)' -deactivate -echo 'TCL_LIBRARY after deactivation: ($env | get -i TCL_LIBRARY)' -" - -# 4. Create another virtual environment -python3.12 -m virtualenv /tmp/venv-investigate2 \ No newline at end of file From 8c9e431fab80a843978a2e3a3aa8f6224e985862 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emre=20=C5=9Eafak?= <3928300+esafak@users.noreply.github.com> Date: Mon, 4 Aug 2025 21:45:08 -0400 Subject: [PATCH 3/4] Iterate on quoting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Emre Şafak <3928300+esafak@users.noreply.github.com> --- src/virtualenv/activation/bash/__init__.py | 8 ++++++++ src/virtualenv/activation/bash/activate.sh | 4 ++-- tests/unit/activation/test_bash.py | 6 +++--- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/virtualenv/activation/bash/__init__.py b/src/virtualenv/activation/bash/__init__.py index 5e095ddf0..fd86a4208 100644 --- a/src/virtualenv/activation/bash/__init__.py +++ b/src/virtualenv/activation/bash/__init__.py @@ -12,6 +12,14 @@ def templates(self): def as_name(self, template): return Path(template).stem + def replacements(self, creator, dest): + data = super().replacements(creator, dest) + data.update({ + "__TCL_LIBRARY__": creator.interpreter.tcl_lib or "", + "__TK_LIBRARY__": creator.interpreter.tk_lib or "", + }) + return data + __all__ = [ "BashActivator", diff --git a/src/virtualenv/activation/bash/activate.sh b/src/virtualenv/activation/bash/activate.sh index ecc8ba038..b54358e9e 100644 --- a/src/virtualenv/activation/bash/activate.sh +++ b/src/virtualenv/activation/bash/activate.sh @@ -79,7 +79,7 @@ if ! [ -z "${PYTHONHOME+_}" ] ; then unset PYTHONHOME fi -if [ "x"__TCL_LIBRARY__ != x ]; then +if [ __TCL_LIBRARY__ != "" ]; then if ! [ -z "${TCL_LIBRARY+_}" ] ; then _OLD_VIRTUAL_TCL_LIBRARY="$TCL_LIBRARY" fi @@ -87,7 +87,7 @@ if [ "x"__TCL_LIBRARY__ != x ]; then export TCL_LIBRARY fi -if [ "x"__TK_LIBRARY__ != x ]; then +if [ __TK_LIBRARY__ != "" ]; then if ! [ -z "${TK_LIBRARY+_}" ] ; then _OLD_VIRTUAL_TK_LIBRARY="$TK_LIBRARY" fi diff --git a/tests/unit/activation/test_bash.py b/tests/unit/activation/test_bash.py index 4ebe5c063..f72705437 100644 --- a/tests/unit/activation/test_bash.py +++ b/tests/unit/activation/test_bash.py @@ -48,16 +48,16 @@ def __init__(self, dest): assert "unset _OLD_VIRTUAL_TK_LIBRARY" in content if present: - assert "if [ /path/to/tcl != \"''\" ]; then" in content + assert "if [ /path/to/tcl != \"\" ]; then" in content assert "TCL_LIBRARY=/path/to/tcl" in content assert "export TCL_LIBRARY" in content - assert "if [ /path/to/tk != \"''\" ]; then" in content + assert "if [ /path/to/tk != \"\" ]; then" in content assert "TK_LIBRARY=/path/to/tk" in content assert "export TK_LIBRARY" in content else: # When not present, the if condition is false, so the block is not executed - assert "if [ '' != \"''\" ]; then" in content + assert "if [ '' != \"\" ]; then" in content, content assert "TCL_LIBRARY=''" in content # The export is inside the if, so this is fine assert "export TCL_LIBRARY" in content From 034f7179dd817a61a3ecfdc68206a3f9a6e935dc Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 5 Aug 2025 01:51:48 +0000 Subject: [PATCH 4/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/unit/activation/test_bash.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/activation/test_bash.py b/tests/unit/activation/test_bash.py index f72705437..0a9c588cf 100644 --- a/tests/unit/activation/test_bash.py +++ b/tests/unit/activation/test_bash.py @@ -48,11 +48,11 @@ def __init__(self, dest): assert "unset _OLD_VIRTUAL_TK_LIBRARY" in content if present: - assert "if [ /path/to/tcl != \"\" ]; then" in content + assert 'if [ /path/to/tcl != "" ]; then' in content assert "TCL_LIBRARY=/path/to/tcl" in content assert "export TCL_LIBRARY" in content - assert "if [ /path/to/tk != \"\" ]; then" in content + assert 'if [ /path/to/tk != "" ]; then' in content assert "TK_LIBRARY=/path/to/tk" in content assert "export TK_LIBRARY" in content else: