mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-16 09:45:01 +00:00
Allow system environments during project environment validity check (#7585)
This commit is contained in:
parent
8259600ca6
commit
9164999f23
5 changed files with 108 additions and 33 deletions
|
@ -37,7 +37,12 @@ pub struct EnvironmentNotFound {
|
|||
#[derive(Clone, Debug, Error)]
|
||||
pub struct InvalidEnvironment {
|
||||
path: PathBuf,
|
||||
reason: String,
|
||||
pub kind: InvalidEnvironmentKind,
|
||||
}
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum InvalidEnvironmentKind {
|
||||
NotDirectory,
|
||||
MissingExecutable(PathBuf),
|
||||
}
|
||||
|
||||
impl From<PythonNotFound> for EnvironmentNotFound {
|
||||
|
@ -110,11 +115,22 @@ impl std::fmt::Display for InvalidEnvironment {
|
|||
f,
|
||||
"Invalid environment at `{}`: {}",
|
||||
self.path.user_display(),
|
||||
self.reason
|
||||
self.kind
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for InvalidEnvironmentKind {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::NotDirectory => write!(f, "expected directory but found a file"),
|
||||
Self::MissingExecutable(path) => {
|
||||
write!(f, "missing Python executable at `{}`", path.user_display())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PythonEnvironment {
|
||||
/// Find a [`PythonEnvironment`] matching the given request and preference.
|
||||
///
|
||||
|
@ -139,6 +155,8 @@ impl PythonEnvironment {
|
|||
}
|
||||
|
||||
/// Create a [`PythonEnvironment`] from the virtual environment at the given root.
|
||||
///
|
||||
/// N.B. This function also works for system Python environments and users depend on this.
|
||||
pub fn from_root(root: impl AsRef<Path>, cache: &Cache) -> Result<Self, Error> {
|
||||
let venv = match fs_err::canonicalize(root.as_ref()) {
|
||||
Ok(venv) => venv,
|
||||
|
@ -154,20 +172,24 @@ impl PythonEnvironment {
|
|||
if venv.is_file() {
|
||||
return Err(InvalidEnvironment {
|
||||
path: venv,
|
||||
reason: "expected directory but found a file".to_string(),
|
||||
kind: InvalidEnvironmentKind::NotDirectory,
|
||||
}
|
||||
.into());
|
||||
}
|
||||
|
||||
if !venv.join("pyvenv.cfg").is_file() {
|
||||
let executable = virtualenv_python_executable(&venv);
|
||||
|
||||
// Check if the executable exists before querying so we can provide a more specific error
|
||||
// Note we intentionally don't require a resolved link to exist here, we're just trying to
|
||||
// tell if this _looks_ like a Python environment.
|
||||
if !(executable.is_symlink() || executable.is_file()) {
|
||||
return Err(InvalidEnvironment {
|
||||
path: venv,
|
||||
reason: "missing a `pyvenv.cfg` marker".to_string(),
|
||||
kind: InvalidEnvironmentKind::MissingExecutable(executable.clone()),
|
||||
}
|
||||
.into());
|
||||
}
|
||||
};
|
||||
|
||||
let executable = virtualenv_python_executable(venv);
|
||||
let interpreter = Interpreter::query(executable, cache)?;
|
||||
|
||||
Ok(Self(Arc::new(PythonEnvironmentShared {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue