mirror of https://github.com/astral-sh/uv
Use `_CONDA_ROOT` to detect conda base environments (#15680)
While investigating https://github.com/astral-sh/uv/pull/15679, I noticed this variable was available in the environment and seems like a nice additional heuristic.
This commit is contained in:
parent
ee5f155f7e
commit
d805d4a370
|
|
@ -1208,6 +1208,7 @@ mod tests {
|
|||
&[
|
||||
("CONDA_PREFIX", Some(baseenv.as_os_str())),
|
||||
("CONDA_DEFAULT_ENV", Some(&OsString::from("base"))),
|
||||
(EnvVars::CONDA_ROOT, None),
|
||||
],
|
||||
|| {
|
||||
find_python_installation(
|
||||
|
|
@ -1231,6 +1232,7 @@ mod tests {
|
|||
&[
|
||||
("CONDA_PREFIX", Some(baseenv.as_os_str())),
|
||||
("CONDA_DEFAULT_ENV", Some(&OsString::from("base"))),
|
||||
(EnvVars::CONDA_ROOT, None),
|
||||
],
|
||||
|| {
|
||||
find_python_installation(
|
||||
|
|
@ -1275,6 +1277,66 @@ mod tests {
|
|||
"We should find the conda environment"
|
||||
);
|
||||
|
||||
// Test _CONDA_ROOT detection of base environment
|
||||
let conda_root_env = context.tempdir.child("conda-root");
|
||||
TestContext::mock_conda_prefix(&conda_root_env, "3.12.2")?;
|
||||
|
||||
// When _CONDA_ROOT matches CONDA_PREFIX, it should be treated as a base environment
|
||||
let result = context.run_with_vars(
|
||||
&[
|
||||
(EnvVars::CONDA_PREFIX, Some(conda_root_env.as_os_str())),
|
||||
(EnvVars::CONDA_ROOT, Some(conda_root_env.as_os_str())),
|
||||
(
|
||||
EnvVars::CONDA_DEFAULT_ENV,
|
||||
Some(&OsString::from("custom-name")),
|
||||
),
|
||||
],
|
||||
|| {
|
||||
find_python_installation(
|
||||
&PythonRequest::Default,
|
||||
EnvironmentPreference::OnlyVirtual,
|
||||
PythonPreference::OnlySystem,
|
||||
&context.cache,
|
||||
Preview::default(),
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
assert!(
|
||||
matches!(result, Err(PythonNotFound { .. })),
|
||||
"Base environment detected via _CONDA_ROOT should be excluded from virtual environments; got {result:?}"
|
||||
);
|
||||
|
||||
// When _CONDA_ROOT doesn't match CONDA_PREFIX, it should be treated as a regular conda environment
|
||||
let other_conda_env = context.tempdir.child("other-conda");
|
||||
TestContext::mock_conda_prefix(&other_conda_env, "3.12.3")?;
|
||||
|
||||
let python = context.run_with_vars(
|
||||
&[
|
||||
(EnvVars::CONDA_PREFIX, Some(other_conda_env.as_os_str())),
|
||||
(EnvVars::CONDA_ROOT, Some(conda_root_env.as_os_str())),
|
||||
(
|
||||
EnvVars::CONDA_DEFAULT_ENV,
|
||||
Some(&OsString::from("custom-env")),
|
||||
),
|
||||
],
|
||||
|| {
|
||||
find_python_installation(
|
||||
&PythonRequest::Default,
|
||||
EnvironmentPreference::OnlyVirtual,
|
||||
PythonPreference::OnlySystem,
|
||||
&context.cache,
|
||||
Preview::default(),
|
||||
)
|
||||
},
|
||||
)??;
|
||||
|
||||
assert_eq!(
|
||||
python.interpreter().python_full_version().to_string(),
|
||||
"3.12.3",
|
||||
"Non-base conda environment should be available for virtual environment preference"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -79,19 +79,27 @@ pub(crate) enum CondaEnvironmentKind {
|
|||
impl CondaEnvironmentKind {
|
||||
/// Whether the given `CONDA_PREFIX` path is the base Conda environment.
|
||||
///
|
||||
/// When the base environment is used, `CONDA_DEFAULT_ENV` will be set to a name, i.e., `base` or
|
||||
/// `root` which does not match the prefix, e.g. `/usr/local` instead of
|
||||
/// `/usr/local/conda/envs/<name>`.
|
||||
/// The base environment is typically stored in a location matching the `_CONDA_ROOT` path.
|
||||
///
|
||||
/// Note the name `CONDA_DEFAULT_ENV` is misleading, it's the current environment, not the base
|
||||
/// environment name.
|
||||
/// Additionally, when the base environment is active, `CONDA_DEFAULT_ENV` will be set to a
|
||||
/// name, e.g., `base`, which does not match the `CONDA_PREFIX`, e.g., `/usr/local` instead of
|
||||
/// `/usr/local/conda/envs/<name>`. Note the name `CONDA_DEFAULT_ENV` is misleading, it's the
|
||||
/// active environment name, not a constant base environment name.
|
||||
fn from_prefix_path(path: &Path) -> Self {
|
||||
// If we cannot read `CONDA_DEFAULT_ENV`, there's no way to know if the base environment
|
||||
// If `_CONDA_ROOT` is set and matches `CONDA_PREFIX`, it's the base environment.
|
||||
if let Ok(conda_root) = env::var(EnvVars::CONDA_ROOT) {
|
||||
if path == Path::new(&conda_root) {
|
||||
return Self::Base;
|
||||
}
|
||||
}
|
||||
|
||||
// Next, we'll use a heuristic based on `CONDA_DEFAULT_ENV`
|
||||
let Ok(current_env) = env::var(EnvVars::CONDA_DEFAULT_ENV) else {
|
||||
return Self::Child;
|
||||
};
|
||||
|
||||
// These are the expected names for the base environment
|
||||
// These are the expected names for the base environment; we may want to remove this
|
||||
// restriction in the future as it's not strictly necessary.
|
||||
if current_env != "base" && current_env != "root" {
|
||||
return Self::Child;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -497,12 +497,15 @@ impl EnvVars {
|
|||
/// Used to detect an activated virtual environment.
|
||||
pub const VIRTUAL_ENV: &'static str = "VIRTUAL_ENV";
|
||||
|
||||
/// Used to detect an activated Conda environment.
|
||||
/// Used to detect the path of an active Conda environment.
|
||||
pub const CONDA_PREFIX: &'static str = "CONDA_PREFIX";
|
||||
|
||||
/// Used to determine if an active Conda environment is the base environment or not.
|
||||
/// Used to determine the name of the active Conda environment.
|
||||
pub const CONDA_DEFAULT_ENV: &'static str = "CONDA_DEFAULT_ENV";
|
||||
|
||||
/// Used to determine the root install path of Conda.
|
||||
pub const CONDA_ROOT: &'static str = "_CONDA_ROOT";
|
||||
|
||||
/// If set to `1` before a virtual environment is activated, then the
|
||||
/// virtual environment name will not be prepended to the terminal prompt.
|
||||
pub const VIRTUAL_ENV_DISABLE_PROMPT: &'static str = "VIRTUAL_ENV_DISABLE_PROMPT";
|
||||
|
|
|
|||
|
|
@ -584,11 +584,15 @@ This is a quasi-standard variable, described, e.g., in `ncurses(3x)`.
|
|||
|
||||
### `CONDA_DEFAULT_ENV`
|
||||
|
||||
Used to determine if an active Conda environment is the base environment or not.
|
||||
Used to determine the name of the active Conda environment.
|
||||
|
||||
### `CONDA_PREFIX`
|
||||
|
||||
Used to detect an activated Conda environment.
|
||||
Used to detect the path of an active Conda environment.
|
||||
|
||||
### `CONDA_ROOT`
|
||||
|
||||
Used to determine the root install path of Conda.
|
||||
|
||||
### `FISH_VERSION`
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue