Visitar URL original
🐛 fix(activation): keep and restore the user's TCL_LIBRARY and TK_LIBRARY by darrenhuai · Pull Request #3234 · pypa/virtualenv · GitHub
Skip to content

🐛 fix(activation): keep and restore the user's TCL_LIBRARY and TK_LIBRARY - #3234

Merged
gaborbernat merged 3 commits into
pypa:mainfrom
darrenhuai:fix/tcl-tk-library-restore
Sep 15, 2026
Merged

gaborbernat merged 3 commits into
pypa:mainfrom
darrenhuai:fix/tcl-tk-library-restore

Conversation

@darrenhuai

@darrenhuai darrenhuai commented Sep 11, 2026 •

Copy link
Copy Markdown
Contributor

Activation sets TCL_LIBRARY and TK_LIBRARY to the interpreter's paths when it knows them, and saves the previous
values for deactivate. Four scripts get this wrong.

PowerShell, fish and csh run deactivate at the start of activation. With no saved copy, their TCL/TK branches removed
the variables, so a user-set TCL_LIBRARY disappeared on activation and stayed gone after deactivate. PowerShell and
csh did this for every environment, fish only when the interpreter has tcl. In PowerShell, setting
$env:TCL_LIBRARY = 'C:\tcl\lib\tcl8.6', then activating and deactivating, left $env:TCL_LIBRARY empty.

bash saved a previous value only when it was non-empty and tested the saved copy with -n. After activating an
environment with tcl, it could not tell "was unset" from "nothing saved", so an unset TCL_LIBRARY stayed at
/usr/lib/tcl8.6 after deactivate.

All four scripts now save the previous value whenever they replace it, as an empty string or $null when it was unset.
deactivate acts only when a saved copy exists (${var+x}, set -q, Test-Path variable:, $?var), restoring a
non-empty value and unsetting otherwise. batch already worked this way.

ActivationTester now prints TCL_LIBRARY and TK_LIBRARY before activation, while active and after deactivation, so
every shell it drives checks them. activation_python adds an environment whose scripts carry tcl paths: the
interpreter reports tcl_lib only when TCL_LIBRARY is set during its cached probe, so the fixture regenerates the
scripts with tcl_lib and tk_lib patched. activation_tester runs each shell with the user's values unset and set.
On main, PowerShell and csh fail the set cases, fish fails set with tcl, and bash fails unset with tcl.

activate.nu never sets these variables (its let $new_env inside if only shadows the outer binding), so the nushell
tester expects them unchanged. This PR leaves that as is.

darrenhuai and others added 3 commits September 11, 2026 00:38
…RARY

The PowerShell script's `deactivate -nondestructive`, which runs at the top of
every activation, treated "no saved copy" as "we set this" and removed whatever
TCL_LIBRARY and TK_LIBRARY the user had exported. On first activation there is
never a saved copy, so any environment, with or without tcl, wiped the user's
values, and the real deactivate then wiped them again instead of restoring. The
fish script did the same, only for environments whose interpreter has tcl
(the block is gated on the template value).

bash had the opposite problem: it only saved a non-empty previous value and
tested the saved copy with -n, so after activating an environment that does set
tcl it could not tell "was unset" from "nothing saved" and left the
environment's tcl path behind for good.

Save the previous value unconditionally (empty or null when unset) whenever the
script is about to replace it, and have deactivate restore or unset based on
whether a saved copy exists at all. csh and batch already work this way and are
unchanged.

Add subprocess tests for bash, fish and PowerShell covering the interpreter
with and without tcl, crossed with the variables set or unset beforehand.
csh ran deactivate before saving TCL_LIBRARY and TK_LIBRARY, and its
unsetenv fallback removed user-set values on every activation. It now saves
an empty value for an unset variable and unsets only when that saved value
is empty.

Instead of a new test per shell, ActivationTester prints TCL_LIBRARY and
TK_LIBRARY before activation, while active and after deactivation.
activation_python adds an environment whose scripts carry tcl paths, and
activation_tester runs each shell with the user's values unset and set.
activate.nu never sets the variables, so its tester expects them unchanged.
@gaborbernat
gaborbernat force-pushed the fix/tcl-tk-library-restore branch from 760c58b to 1c1539e Compare September 15, 2026 22:17
@gaborbernat
gaborbernat merged commit 973298a into pypa:main Sep 15, 2026
59 checks passed
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.

2 participants