mirror of
https://github.com/astral-sh/uv.git
synced 2025-08-30 07:17:26 +00:00
Patch Python executable name for Windows free-threaded builds (#8310)
A temporary fix for https://github.com/astral-sh/uv/issues/8298 while we
wait for my slower upstream fix at
https://github.com/indygreg/python-build-standalone/pull/373
I think we'll want this machinery anyway to ensure that the various
executable names are available? Otherwise we need to special-case all
the `python` names in `uv run`?
We don't have unit test coverage of managed downloads, so I added an
[integration
test](3170395680
)
similar to what we have for Linux.
This commit is contained in:
parent
3fd69b448e
commit
c8cbd62a30
5 changed files with 114 additions and 1 deletions
|
@ -142,6 +142,7 @@ impl PythonInstallation {
|
|||
|
||||
let installed = ManagedPythonInstallation::new(path)?;
|
||||
installed.ensure_externally_managed()?;
|
||||
installed.ensure_canonical_executables()?;
|
||||
|
||||
Ok(Self {
|
||||
source: PythonSource::Managed,
|
||||
|
|
|
@ -7,7 +7,7 @@ use std::io::{self, Write};
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
use thiserror::Error;
|
||||
use tracing::warn;
|
||||
use tracing::{debug, warn};
|
||||
|
||||
use uv_state::{StateBucket, StateStore};
|
||||
|
||||
|
@ -44,6 +44,15 @@ pub enum Error {
|
|||
#[source]
|
||||
err: io::Error,
|
||||
},
|
||||
#[error("Missing expected Python executable at {}", _0.user_display())]
|
||||
MissingExecutable(PathBuf),
|
||||
#[error("Failed to create canonical Python executable at {} from {}", to.user_display(), from.user_display())]
|
||||
CanonicalizeExecutable {
|
||||
from: PathBuf,
|
||||
to: PathBuf,
|
||||
#[source]
|
||||
err: io::Error,
|
||||
},
|
||||
#[error("Failed to read Python installation directory: {0}", dir.user_display())]
|
||||
ReadError {
|
||||
dir: PathBuf,
|
||||
|
@ -323,6 +332,48 @@ impl ManagedPythonInstallation {
|
|||
}
|
||||
}
|
||||
|
||||
/// Ensure the environment contains the canonical Python executable names.
|
||||
pub fn ensure_canonical_executables(&self) -> Result<(), Error> {
|
||||
let python = self.executable();
|
||||
|
||||
// Workaround for python-build-standalone v20241016 which is missing the standard
|
||||
// `python.exe` executable in free-threaded distributions on Windows.
|
||||
//
|
||||
// See https://github.com/astral-sh/uv/issues/8298
|
||||
if !python.try_exists()? {
|
||||
match self.key.variant {
|
||||
PythonVariant::Default => return Err(Error::MissingExecutable(python.clone())),
|
||||
PythonVariant::Freethreaded => {
|
||||
// This is the alternative executable name for the freethreaded variant
|
||||
let python_in_dist = self.python_dir().join(format!(
|
||||
"python{}.{}t{}",
|
||||
self.key.major,
|
||||
self.key.minor,
|
||||
std::env::consts::EXE_SUFFIX
|
||||
));
|
||||
debug!(
|
||||
"Creating link {} -> {}",
|
||||
python.user_display(),
|
||||
python_in_dist.user_display()
|
||||
);
|
||||
uv_fs::symlink_copy_fallback_file(&python_in_dist, &python).map_err(|err| {
|
||||
if err.kind() == io::ErrorKind::NotFound {
|
||||
Error::MissingExecutable(python_in_dist.clone())
|
||||
} else {
|
||||
Error::CanonicalizeExecutable {
|
||||
from: python_in_dist,
|
||||
to: python,
|
||||
err,
|
||||
}
|
||||
}
|
||||
})?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Ensure the environment is marked as externally managed with the
|
||||
/// standard `EXTERNALLY-MANAGED` file.
|
||||
pub fn ensure_externally_managed(&self) -> Result<(), Error> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue