diff --git a/routes/cookbook_helpers.py b/routes/cookbook_helpers.py index d06af50d7..bb819f3f8 100644 --- a/routes/cookbook_helpers.py +++ b/routes/cookbook_helpers.py @@ -362,7 +362,12 @@ def _user_shell_path_bootstrap() -> list[str]: ' ODYSSEUS_USER_PATH="$("$ODYSSEUS_USER_SHELL" -ic \'printf "__ODYSSEUS_PATH__%s\\n" "$PATH"\' 2>/dev/null | sed -n \'s/^__ODYSSEUS_PATH__//p\' | tail -n 1 || true)"', ' if [ -n "$ODYSSEUS_USER_PATH" ]; then export PATH="$ODYSSEUS_USER_PATH:$PATH"; fi', 'fi', - 'command -v python3 >/dev/null 2>&1 || python3() { python "$@"; }', + # Windows can expose python3 as a Microsoft Store App Execution Alias + # under WindowsApps. Git Bash sees that stub as present, but it exits + # before running Python. A Windows venv usually has python.exe, not + # python3.exe, so treat a missing or WindowsApps python3 as absent. + '_odys_py3="$(command -v python3 2>/dev/null || true)"', + 'case "$_odys_py3" in ""|*[Ww]indows[Aa]pps*) python3() { python "$@"; } ;; esac', 'command -v python >/dev/null 2>&1 || python() { python3 "$@"; }', ] diff --git a/tests/test_cookbook_helpers.py b/tests/test_cookbook_helpers.py index a02de24c0..b83cbdf93 100644 --- a/tests/test_cookbook_helpers.py +++ b/tests/test_cookbook_helpers.py @@ -468,7 +468,13 @@ def test_local_tooling_path_export_converts_windows_paths_for_bash(): def test_user_shell_path_bootstrap_falls_back_to_python_on_windows_bash(): script = "\n".join(_user_shell_path_bootstrap()) - assert 'command -v python3 >/dev/null 2>&1 || python3() { python "$@"; }' in script + # A missing python3 OR a Microsoft Store App Execution Alias stub under + # WindowsApps must shim python3 -> python so the venv interpreter is used. + assert '_odys_py3="$(command -v python3 2>/dev/null || true)"' in script + assert ( + 'case "$_odys_py3" in ""|*[Ww]indows[Aa]pps*) python3() { python "$@"; } ;; esac' + in script + ) assert 'command -v python >/dev/null 2>&1 || python() { python3 "$@"; }' in script