From 3e6fe1da8616bf813217130664d68329cc33e760 Mon Sep 17 00:00:00 2001 From: konsti Date: Thu, 9 Oct 2025 16:34:40 +0200 Subject: [PATCH] Allow missing `Scripts` directory (#16206) With the new Python install manager, the `Scripts` directory reported by Python may not exist. See https://github.com/astral-sh/uv/pull/16205 for a failing CI run: https://github.com/astral-sh/uv/actions/runs/18377230241/job/52354460636?pr=16205#step:4:15 Fixes https://github.com/astral-sh/uv/issues/16204 --- .github/workflows/ci.yml | 24 +++++++++++++++++ crates/uv/src/commands/project/run.rs | 39 ++++++++++++--------------- 2 files changed, 41 insertions(+), 22 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cecf1d583..2996e5e0a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1289,6 +1289,30 @@ jobs: ./uv run python -c "" ./uv run -p 3.13 python -c "" + integration-test-windows-python-install-manager: + timeout-minutes: 10 + needs: build-binary-windows-x86_64 + name: "integration test | windows python install manager" + runs-on: windows-latest + + steps: + - name: "Download binary" + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + with: + name: uv-windows-x86_64-${{ github.sha }} + + - name: "Install Python via Python Install manager" + run: | + # https://www.python.org/downloads/release/pymanager-250/ + winget install --accept-package-agreements --accept-source-agreements 9NQ7512CXL7T + # Call Python Install Manager's py.exe by full path to avoid legacy py.exe + & "$env:LOCALAPPDATA\Microsoft\WindowsApps\py.exe" install 3.14 + + # https://github.com/astral-sh/uv/issues/16204 + - name: "Check temporary environment creation" + run: | + ./uv run -p $env:LOCALAPPDATA\Python\pythoncore-3.14-64\python.exe --with numpy python -c "import sys; print(sys.executable)" + integration-test-pypy-linux: timeout-minutes: 10 needs: build-binary-linux-libc diff --git a/crates/uv/src/commands/project/run.rs b/crates/uv/src/commands/project/run.rs index a6ff4caca..fa3227c45 100644 --- a/crates/uv/src/commands/project/run.rs +++ b/crates/uv/src/commands/project/run.rs @@ -2,6 +2,7 @@ use std::borrow::Cow; use std::env::VarError; use std::ffi::OsString; use std::fmt::Write; +use std::io; use std::io::Read; use std::path::{Path, PathBuf}; @@ -1099,7 +1100,12 @@ hint: If you are running a script with `{}` in the shebang, you may need to incl // Copy each entrypoint from the base environments to the ephemeral environment, // updating the Python executable target to ensure they run in the ephemeral // environment. - for entry in fs_err::read_dir(interpreter.scripts())? { + let scripts = match fs_err::read_dir(interpreter.scripts()) { + Ok(scripts) => scripts, + Err(err) if err.kind() == io::ErrorKind::NotFound => continue, + Err(err) => return Err(err.into()), + }; + for entry in scripts { let entry = entry?; if !entry.file_type()?.is_file() { continue; @@ -1200,23 +1206,13 @@ hint: If you are running a script with `{}` in the shebang, you may need to incl "Provide a command or script to invoke with `uv run ` or `uv run