Skip to content

Commit 46c61a6

Browse files
authored
Upgrade venv to v3.13.11 (#6459)
* Upgrade venv * get_venv_base_executable * mark failing tests
1 parent ab1105a commit 46c61a6

File tree

9 files changed

+1065
-308
lines changed

9 files changed

+1065
-308
lines changed

Lib/test/test_venv.py

Lines changed: 562 additions & 53 deletions
Large diffs are not rendered by default.

Lib/venv/__init__.py

Lines changed: 392 additions & 215 deletions
Large diffs are not rendered by default.

Lib/venv/__main__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66
main()
77
rc = 0
88
except Exception as e:
9-
print('Error: %s' % e, file=sys.stderr)
9+
print('Error:', e, file=sys.stderr)
1010
sys.exit(rc)

Lib/venv/scripts/common/Activate.ps1

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,8 @@ deactivate -nondestructive
219219
# that there is an activated venv.
220220
$env:VIRTUAL_ENV = $VenvDir
221221

222+
$env:VIRTUAL_ENV_PROMPT = $Prompt
223+
222224
if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) {
223225

224226
Write-Verbose "Setting prompt to '$Prompt'"
@@ -233,7 +235,6 @@ if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) {
233235
Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) "
234236
_OLD_VIRTUAL_PROMPT
235237
}
236-
$env:VIRTUAL_ENV_PROMPT = $Prompt
237238
}
238239

239240
# Clear PYTHONHOME

Lib/venv/scripts/common/activate

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# This file must be used with "source bin/activate" *from bash*
2-
# you cannot run it directly
2+
# You cannot run it directly
33

44
deactivate () {
55
# reset old environment variables
@@ -14,12 +14,10 @@ deactivate () {
1414
unset _OLD_VIRTUAL_PYTHONHOME
1515
fi
1616

17-
# This should detect bash and zsh, which have a hash command that must
18-
# be called to get it to forget past commands. Without forgetting
19-
# past commands the $PATH changes we made may not be respected
20-
if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then
21-
hash -r 2> /dev/null
22-
fi
17+
# Call hash to forget past locations. Without forgetting
18+
# past locations the $PATH changes we made may not be respected.
19+
# See "man bash" for more details. hash is usually a builtin of your shell
20+
hash -r 2> /dev/null
2321

2422
if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then
2523
PS1="${_OLD_VIRTUAL_PS1:-}"
@@ -38,13 +36,27 @@ deactivate () {
3836
# unset irrelevant variables
3937
deactivate nondestructive
4038

41-
VIRTUAL_ENV="__VENV_DIR__"
42-
export VIRTUAL_ENV
39+
# on Windows, a path can contain colons and backslashes and has to be converted:
40+
case "$(uname)" in
41+
CYGWIN*|MSYS*|MINGW*)
42+
# transform D:\path\to\venv to /d/path/to/venv on MSYS and MINGW
43+
# and to /cygdrive/d/path/to/venv on Cygwin
44+
VIRTUAL_ENV=$(cygpath __VENV_DIR__)
45+
export VIRTUAL_ENV
46+
;;
47+
*)
48+
# use the path as-is
49+
export VIRTUAL_ENV=__VENV_DIR__
50+
;;
51+
esac
4352

4453
_OLD_VIRTUAL_PATH="$PATH"
45-
PATH="$VIRTUAL_ENV/__VENV_BIN_NAME__:$PATH"
54+
PATH="$VIRTUAL_ENV/"__VENV_BIN_NAME__":$PATH"
4655
export PATH
4756

57+
VIRTUAL_ENV_PROMPT=__VENV_PROMPT__
58+
export VIRTUAL_ENV_PROMPT
59+
4860
# unset PYTHONHOME if set
4961
# this will fail if PYTHONHOME is set to the empty string (which is bad anyway)
5062
# could use `if (set -u; : $PYTHONHOME) ;` in bash
@@ -55,15 +67,10 @@ fi
5567

5668
if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then
5769
_OLD_VIRTUAL_PS1="${PS1:-}"
58-
PS1="__VENV_PROMPT__${PS1:-}"
70+
PS1="("__VENV_PROMPT__") ${PS1:-}"
5971
export PS1
60-
VIRTUAL_ENV_PROMPT="__VENV_PROMPT__"
61-
export VIRTUAL_ENV_PROMPT
6272
fi
6373

64-
# This should detect bash and zsh, which have a hash command that must
65-
# be called to get it to forget past commands. Without forgetting
74+
# Call hash to forget past commands. Without forgetting
6675
# past commands the $PATH changes we made may not be respected
67-
if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then
68-
hash -r 2> /dev/null
69-
fi
76+
hash -r 2> /dev/null
Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# This file must be used with "source <venv>/bin/activate.fish" *from fish*
2-
# (https://fishshell.com/); you cannot run it directly.
2+
# (https://fishshell.com/). You cannot run it directly.
33

44
function deactivate -d "Exit virtual environment and return to normal shell environment"
55
# reset old environment variables
@@ -13,10 +13,13 @@ function deactivate -d "Exit virtual environment and return to normal shell env
1313
end
1414

1515
if test -n "$_OLD_FISH_PROMPT_OVERRIDE"
16-
functions -e fish_prompt
1716
set -e _OLD_FISH_PROMPT_OVERRIDE
18-
functions -c _old_fish_prompt fish_prompt
19-
functions -e _old_fish_prompt
17+
# prevents error when using nested fish instances (Issue #93858)
18+
if functions -q _old_fish_prompt
19+
functions -e fish_prompt
20+
functions -c _old_fish_prompt fish_prompt
21+
functions -e _old_fish_prompt
22+
end
2023
end
2124

2225
set -e VIRTUAL_ENV
@@ -30,10 +33,11 @@ end
3033
# Unset irrelevant variables.
3134
deactivate nondestructive
3235

33-
set -gx VIRTUAL_ENV "__VENV_DIR__"
36+
set -gx VIRTUAL_ENV __VENV_DIR__
3437

3538
set -gx _OLD_VIRTUAL_PATH $PATH
36-
set -gx PATH "$VIRTUAL_ENV/__VENV_BIN_NAME__" $PATH
39+
set -gx PATH "$VIRTUAL_ENV/"__VENV_BIN_NAME__ $PATH
40+
set -gx VIRTUAL_ENV_PROMPT __VENV_PROMPT__
3741

3842
# Unset PYTHONHOME if set.
3943
if set -q PYTHONHOME
@@ -53,7 +57,7 @@ if test -z "$VIRTUAL_ENV_DISABLE_PROMPT"
5357
set -l old_status $status
5458

5559
# Output the venv prompt; color taken from the blue of the Python logo.
56-
printf "%s%s%s" (set_color 4B8BBE) "__VENV_PROMPT__" (set_color normal)
60+
printf "%s(%s)%s " (set_color 4B8BBE) __VENV_PROMPT__ (set_color normal)
5761

5862
# Restore the return status of the previous command.
5963
echo "exit $old_status" | .
@@ -62,5 +66,4 @@ if test -z "$VIRTUAL_ENV_DISABLE_PROMPT"
6266
end
6367

6468
set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV"
65-
set -gx VIRTUAL_ENV_PROMPT "__VENV_PROMPT__"
6669
end

Lib/venv/scripts/nt/activate.bat

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,24 @@ if defined _OLD_CODEPAGE (
88
"%SystemRoot%\System32\chcp.com" 65001 > nul
99
)
1010

11-
set VIRTUAL_ENV=__VENV_DIR__
11+
set "VIRTUAL_ENV=__VENV_DIR__"
1212

1313
if not defined PROMPT set PROMPT=$P$G
1414

1515
if defined _OLD_VIRTUAL_PROMPT set PROMPT=%_OLD_VIRTUAL_PROMPT%
1616
if defined _OLD_VIRTUAL_PYTHONHOME set PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%
1717

18-
set _OLD_VIRTUAL_PROMPT=%PROMPT%
19-
set PROMPT=__VENV_PROMPT__%PROMPT%
18+
set "_OLD_VIRTUAL_PROMPT=%PROMPT%"
19+
set "PROMPT=(__VENV_PROMPT__) %PROMPT%"
2020

2121
if defined PYTHONHOME set _OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME%
2222
set PYTHONHOME=
2323

2424
if defined _OLD_VIRTUAL_PATH set PATH=%_OLD_VIRTUAL_PATH%
2525
if not defined _OLD_VIRTUAL_PATH set _OLD_VIRTUAL_PATH=%PATH%
2626

27-
set PATH=%VIRTUAL_ENV%\__VENV_BIN_NAME__;%PATH%
28-
set VIRTUAL_ENV_PROMPT=__VENV_PROMPT__
27+
set "PATH=%VIRTUAL_ENV%\__VENV_BIN_NAME__;%PATH%"
28+
set "VIRTUAL_ENV_PROMPT=__VENV_PROMPT__"
2929

3030
:END
3131
if defined _OLD_CODEPAGE (

Lib/venv/scripts/posix/activate.csh

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# This file must be used with "source bin/activate.csh" *from csh*.
22
# You cannot run it directly.
3+
34
# Created by Davide Di Blasi <davidedb@gmail.com>.
45
# Ported to Python 3.3 venv by Andrew Svetlov <andrew.svetlov@gmail.com>
56

@@ -8,17 +9,17 @@ alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PA
89
# Unset irrelevant variables.
910
deactivate nondestructive
1011

11-
setenv VIRTUAL_ENV "__VENV_DIR__"
12+
setenv VIRTUAL_ENV __VENV_DIR__
1213

1314
set _OLD_VIRTUAL_PATH="$PATH"
14-
setenv PATH "$VIRTUAL_ENV/__VENV_BIN_NAME__:$PATH"
15+
setenv PATH "$VIRTUAL_ENV/"__VENV_BIN_NAME__":$PATH"
16+
setenv VIRTUAL_ENV_PROMPT __VENV_PROMPT__
1517

1618

1719
set _OLD_VIRTUAL_PROMPT="$prompt"
1820

1921
if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then
20-
set prompt = "__VENV_PROMPT__$prompt"
21-
setenv VIRTUAL_ENV_PROMPT "__VENV_PROMPT__"
22+
set prompt = "("__VENV_PROMPT__") $prompt:q"
2223
endif
2324

2425
alias pydoc python -m pydoc

crates/vm/src/stdlib/sys.rs

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,11 +164,70 @@ mod sys {
164164
#[pyattr]
165165
fn _base_executable(vm: &VirtualMachine) -> PyObjectRef {
166166
let ctx = &vm.ctx;
167+
// First check __PYVENV_LAUNCHER__ environment variable
167168
if let Ok(var) = env::var("__PYVENV_LAUNCHER__") {
168-
ctx.new_str(var).into()
169-
} else {
170-
executable(vm)
169+
return ctx.new_str(var).into();
170+
}
171+
172+
// Try to detect if we're running from a venv by looking for pyvenv.cfg
173+
if let Some(base_exe) = get_venv_base_executable() {
174+
return ctx.new_str(base_exe).into();
171175
}
176+
177+
executable(vm)
178+
}
179+
180+
/// Try to find base executable from pyvenv.cfg (see getpath.py)
181+
fn get_venv_base_executable() -> Option<String> {
182+
// TODO: This is a minimal implementation of getpath.py
183+
// To fully support all cases, `getpath.py` should be placed in @crates/vm/Lib/python_builtins/
184+
185+
// Get current executable path
186+
#[cfg(not(target_arch = "wasm32"))]
187+
let exe_path = {
188+
let exec_arg = env::args_os().next()?;
189+
which::which(exec_arg).ok()?
190+
};
191+
#[cfg(target_arch = "wasm32")]
192+
let exe_path = {
193+
let exec_arg = env::args().next()?;
194+
path::PathBuf::from(exec_arg)
195+
};
196+
197+
let exe_dir = exe_path.parent()?;
198+
let exe_name = exe_path.file_name()?;
199+
200+
// Look for pyvenv.cfg in parent directory (typical venv layout: venv/bin/python)
201+
let venv_dir = exe_dir.parent()?;
202+
let pyvenv_cfg = venv_dir.join("pyvenv.cfg");
203+
204+
if !pyvenv_cfg.exists() {
205+
return None;
206+
}
207+
208+
// Parse pyvenv.cfg and extract home directory
209+
let content = std::fs::read_to_string(&pyvenv_cfg).ok()?;
210+
211+
for line in content.lines() {
212+
if let Some((key, value)) = line.split_once('=') {
213+
let key = key.trim().to_lowercase();
214+
let value = value.trim();
215+
216+
if key == "home" {
217+
// First try to resolve symlinks (getpath.py line 373-377)
218+
if let Ok(resolved) = std::fs::canonicalize(&exe_path)
219+
&& resolved != exe_path
220+
{
221+
return Some(resolved.to_string_lossy().into_owned());
222+
}
223+
// Fallback: home_dir + executable_name (getpath.py line 381)
224+
let base_exe = path::Path::new(value).join(exe_name);
225+
return Some(base_exe.to_string_lossy().into_owned());
226+
}
227+
}
228+
}
229+
230+
None
172231
}
173232

174233
#[pyattr]

0 commit comments

Comments
 (0)