From 70143b86264fa6c69e73162b27d739db2820ae74 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Mon, 4 Mar 2024 13:49:17 -0800 Subject: [PATCH] Run Windows against Python 3.13 (#2171) ## Summary In Python 3.13, at least in the current builds, there's no `python.exe`, but there is `venvlauncher.exe`. I've asked here about whether it's intended: https://discuss.python.org/t/when-should-venv-scripts-nt-python-exe-be-present/47620. But there's at least some evidence in CPython [here](https://github.com/python/cpython/blob/d457345bbc6414db0443819290b04a9a4333313d/Lib/venv/__init__.py#L270) that we should fall back to these, and the tests pass. Closes https://github.com/astral-sh/uv/issues/1636. --- .github/workflows/system-install.yml | 36 ++++++++++++++++++++++++++-- crates/uv-virtualenv/src/bare.rs | 21 +++++++++++++++- 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/.github/workflows/system-install.yml b/.github/workflows/system-install.yml index 011fb08cd..a96a38447 100644 --- a/.github/workflows/system-install.yml +++ b/.github/workflows/system-install.yml @@ -61,8 +61,8 @@ jobs: - name: "Validate global Python install" run: python3.11 scripts/check_system_python.py --uv ./target/debug/uv - install-windows: - name: "Install Python on Windows" + install-windows-python-310: + name: "Install Python 3.10 on Windows" runs-on: windows-latest steps: - uses: actions/checkout@v4 @@ -82,9 +82,41 @@ jobs: - name: "Print Python path" run: echo $(which python) + - name: "Create virtual environment" + run: ./target/debug/uv venv + - name: "Validate global Python install" run: py -3.10 ./scripts/check_system_python.py --uv ./target/debug/uv + install-windows-python-313: + name: "Install Python 3.13 on Windows" + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.13" + allow-prereleases: true + cache: pip + + - name: "Install Rust toolchain" + run: rustup show + + - uses: Swatinem/rust-cache@v2 + + - name: "Build" + run: cargo build + + - name: "Print Python path" + run: echo $(which python) + + - name: "Create virtual environment" + run: ./target/debug/uv venv + + - name: "Validate global Python install" + run: py -3.13 ./scripts/check_system_python.py --uv ./target/debug/uv + install-pyenv: name: "Install Python using pyenv" runs-on: ubuntu-latest diff --git a/crates/uv-virtualenv/src/bare.rs b/crates/uv-virtualenv/src/bare.rs index 55b1ded68..d4cc26ca1 100644 --- a/crates/uv-virtualenv/src/bare.rs +++ b/crates/uv-virtualenv/src/bare.rs @@ -176,7 +176,26 @@ pub fn create_bare_venv( .join("scripts") .join("nt") .join(python_exe); - fs_err::copy(shim, scripts.join(python_exe))?; + match fs_err::copy(shim, scripts.join(python_exe)) { + Ok(_) => {} + Err(err) if err.kind() == io::ErrorKind::NotFound => { + // If `python.exe` doesn't exist, try the `venvlaucher.exe` shim. + let shim = interpreter + .stdlib() + .join("venv") + .join("scripts") + .join("nt") + .join(match python_exe { + "python.exe" => "venvwlauncher.exe", + "pythonw.exe" => "venvwlauncher.exe", + _ => unreachable!(), + }); + fs_err::copy(shim, scripts.join(python_exe))?; + } + Err(err) => { + return Err(err.into()); + } + } } } #[cfg(not(any(unix, windows)))]