mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-17 22:07:42 +00:00
[ty] improve base conda distinction from child conda (#20675)
<!-- Thank you for contributing to Ruff/ty! To help us out with reviewing, please consider the following: - Does this pull request include a summary of the change? (See below.) - Does this pull request include a descriptive title? (Please prefix with `[ty]` for ty pull requests.) - Does this pull request include references to any relevant issues? --> ## Summary #19990 didn't completely fix the base vs. child conda environment distinction, since it detected slightly different behavior than what I usually see in conda. E.g., I see something like the following: ``` (didn't yet activate conda, but base is active) ➜ printenv | grep CONDA CONDA_PYTHON_EXE=/opt/anaconda3/bin/python CONDA_PREFIX=/opt/anaconda3 CONDA_DEFAULT_ENV=base CONDA_EXE=/opt/anaconda3/bin/conda CONDA_SHLVL=1 CONDA_PROMPT_MODIFIER=(base) (activating conda) ➜ conda activate test (test is an active conda environment) ❯ printenv | grep CONDA CONDA_PREFIX=/opt/anaconda3/envs/test CONDA_PYTHON_EXE=/opt/anaconda3/bin/python CONDA_SHLVL=2 CONDA_PREFIX_1=/opt/anaconda3 CONDA_DEFAULT_ENV=test CONDA_PROMPT_MODIFIER=(test) CONDA_EXE=/opt/anaconda3/bin/conda ``` But the current behavior looks for `CONDA_DEFAULT_ENV = basename(CONDA_PREFIX)` for the base environment instead of the child environment, where we actually see this equality. This pull request fixes that and updates the tests correspondingly. ## Test Plan I updated the existing tests with the new behavior. Let me know if you want more tests. Note: It shouldn't be necessary to test for the case where we have `conda/envs/base`, since one should not be able to create such an environment (one with the name of `CONDA_DEFAULT_ENV`). --------- Co-authored-by: Aria Desires <aria.desires@gmail.com>
This commit is contained in:
parent
ebfb33c30b
commit
f73ead11cb
4 changed files with 221 additions and 101 deletions
|
@ -614,28 +614,44 @@ pub(crate) enum CondaEnvironmentKind {
|
|||
impl CondaEnvironmentKind {
|
||||
/// Compute the kind of `CONDA_PREFIX` we have.
|
||||
///
|
||||
/// 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.
|
||||
///
|
||||
/// 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 that the name `CONDA_DEFAULT_ENV` is misleading, it's
|
||||
/// the active environment name, not a constant base environment name.
|
||||
fn from_prefix_path(system: &dyn System, path: &SystemPath) -> Self {
|
||||
// If we cannot read `CONDA_DEFAULT_ENV`, there's no way to know if the base environment
|
||||
let Ok(default_env) = system.env_var(EnvVars::CONDA_DEFAULT_ENV) else {
|
||||
return CondaEnvironmentKind::Child;
|
||||
};
|
||||
|
||||
// These are the expected names for the base environment
|
||||
if default_env != "base" && default_env != "root" {
|
||||
return CondaEnvironmentKind::Child;
|
||||
// If `_CONDA_ROOT` is set and matches `CONDA_PREFIX`, it's the base environment.
|
||||
if let Ok(conda_root) = system.env_var(EnvVars::CONDA_ROOT) {
|
||||
if path.as_str() == conda_root {
|
||||
return Self::Base;
|
||||
}
|
||||
}
|
||||
|
||||
let Some(name) = path.file_name() else {
|
||||
return CondaEnvironmentKind::Child;
|
||||
// Next, we'll use a heuristic based on `CONDA_DEFAULT_ENV`
|
||||
let Ok(current_env) = system.env_var(EnvVars::CONDA_DEFAULT_ENV) else {
|
||||
return Self::Child;
|
||||
};
|
||||
|
||||
if name == default_env {
|
||||
CondaEnvironmentKind::Base
|
||||
// If the environment name is "base" or "root", treat it as a base environment
|
||||
//
|
||||
// These are the expected names for the base environment; and is retained for backwards
|
||||
// compatibility, but in a future breaking release we should remove this special-casing.
|
||||
if current_env == "base" || current_env == "root" {
|
||||
return Self::Base;
|
||||
}
|
||||
|
||||
// For other environment names, use the path-based logic
|
||||
let Some(name) = path.file_name() else {
|
||||
return Self::Child;
|
||||
};
|
||||
|
||||
// If the environment is in a directory matching the name of the environment, it's not
|
||||
// usually a base environment.
|
||||
if name == current_env {
|
||||
Self::Child
|
||||
} else {
|
||||
CondaEnvironmentKind::Child
|
||||
Self::Base
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue