mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-02 22:55:08 +00:00
[red-knot] Discover local venv folder in cli (#16917)
<!--
Thank you for contributing to Ruff! 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?
- Does this pull request include references to any relevant issues?
-->
## Summary
Fixes #16744
Code from
bbf4f830b5/crates/uv-python/src/virtualenv.rs (L124-L144)
## Test Plan
Manual testing
---------
Co-authored-by: Micha Reiser <micha@reiser.io>
This commit is contained in:
parent
aca6254e82
commit
0e48940ea4
4 changed files with 53 additions and 2 deletions
|
@ -121,7 +121,7 @@ impl Options {
|
||||||
.ok()
|
.ok()
|
||||||
.map(PythonPath::from_virtual_env_var)
|
.map(PythonPath::from_virtual_env_var)
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| PythonPath::KnownSitePackages(vec![])),
|
.unwrap_or(PythonPath::Discover),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ use ruff_python_ast::PythonVersion;
|
||||||
use crate::db::Db;
|
use crate::db::Db;
|
||||||
use crate::module_name::ModuleName;
|
use crate::module_name::ModuleName;
|
||||||
use crate::module_resolver::typeshed::{vendored_typeshed_versions, TypeshedVersions};
|
use crate::module_resolver::typeshed::{vendored_typeshed_versions, TypeshedVersions};
|
||||||
use crate::site_packages::VirtualEnvironment;
|
use crate::site_packages::{SitePackagesDiscoveryError, SysPrefixPathOrigin, VirtualEnvironment};
|
||||||
use crate::{Program, PythonPath, SearchPathSettings};
|
use crate::{Program, PythonPath, SearchPathSettings};
|
||||||
|
|
||||||
use super::module::{Module, ModuleKind};
|
use super::module::{Module, ModuleKind};
|
||||||
|
@ -133,6 +133,22 @@ pub(crate) fn search_paths(db: &dyn Db) -> SearchPathIterator {
|
||||||
Program::get(db).search_paths(db).iter(db)
|
Program::get(db).search_paths(db).iter(db)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Searches for a `.venv` directory in the current or any parent directory
|
||||||
|
fn virtual_env_from_working_dir() -> Option<SystemPathBuf> {
|
||||||
|
let current_dir = std::env::current_dir().ok()?;
|
||||||
|
|
||||||
|
for dir in current_dir.ancestors() {
|
||||||
|
let dot_venv = dir.join(".venv");
|
||||||
|
if dot_venv.is_dir() {
|
||||||
|
if !dot_venv.join("pyvenv.cfg").is_file() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
return SystemPathBuf::from_path_buf(dot_venv).ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct SearchPaths {
|
pub struct SearchPaths {
|
||||||
/// Search paths that have been statically determined purely from reading Ruff's configuration settings.
|
/// Search paths that have been statically determined purely from reading Ruff's configuration settings.
|
||||||
|
@ -235,6 +251,37 @@ impl SearchPaths {
|
||||||
.and_then(|venv| venv.site_packages_directories(system))?
|
.and_then(|venv| venv.site_packages_directories(system))?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PythonPath::Discover => {
|
||||||
|
tracing::debug!("Discovering virtual environment");
|
||||||
|
let virtual_env_path = virtual_env_from_working_dir();
|
||||||
|
if let Some(virtual_env_path) = virtual_env_path {
|
||||||
|
tracing::debug!("Found `.venv` folder at '{}'", virtual_env_path);
|
||||||
|
|
||||||
|
let handle_invalid_virtual_env = |error: SitePackagesDiscoveryError| {
|
||||||
|
tracing::debug!(
|
||||||
|
"Ignoring automatically detected virtual environment at '{}': {}",
|
||||||
|
virtual_env_path,
|
||||||
|
error
|
||||||
|
);
|
||||||
|
vec![]
|
||||||
|
};
|
||||||
|
|
||||||
|
match VirtualEnvironment::new(
|
||||||
|
virtual_env_path.clone(),
|
||||||
|
SysPrefixPathOrigin::LocalVenv,
|
||||||
|
system,
|
||||||
|
) {
|
||||||
|
Ok(venv) => venv
|
||||||
|
.site_packages_directories(system)
|
||||||
|
.unwrap_or_else(handle_invalid_virtual_env),
|
||||||
|
Err(error) => handle_invalid_virtual_env(error),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tracing::debug!("No virtual environment found");
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PythonPath::KnownSitePackages(paths) => paths
|
PythonPath::KnownSitePackages(paths) => paths
|
||||||
.iter()
|
.iter()
|
||||||
.map(|path| canonicalize(path, system))
|
.map(|path| canonicalize(path, system))
|
||||||
|
|
|
@ -145,6 +145,8 @@ pub enum PythonPath {
|
||||||
/// [`sys.prefix`]: https://docs.python.org/3/library/sys.html#sys.prefix
|
/// [`sys.prefix`]: https://docs.python.org/3/library/sys.html#sys.prefix
|
||||||
SysPrefix(SystemPathBuf, SysPrefixPathOrigin),
|
SysPrefix(SystemPathBuf, SysPrefixPathOrigin),
|
||||||
|
|
||||||
|
Discover,
|
||||||
|
|
||||||
/// Resolved site packages paths.
|
/// Resolved site packages paths.
|
||||||
///
|
///
|
||||||
/// This variant is mainly intended for testing where we want to skip resolving `site-packages`
|
/// This variant is mainly intended for testing where we want to skip resolving `site-packages`
|
||||||
|
|
|
@ -459,6 +459,7 @@ pub enum SysPrefixPathOrigin {
|
||||||
PythonCliFlag,
|
PythonCliFlag,
|
||||||
VirtualEnvVar,
|
VirtualEnvVar,
|
||||||
Derived,
|
Derived,
|
||||||
|
LocalVenv,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for SysPrefixPathOrigin {
|
impl Display for SysPrefixPathOrigin {
|
||||||
|
@ -467,6 +468,7 @@ impl Display for SysPrefixPathOrigin {
|
||||||
Self::PythonCliFlag => f.write_str("`--python` argument"),
|
Self::PythonCliFlag => f.write_str("`--python` argument"),
|
||||||
Self::VirtualEnvVar => f.write_str("`VIRTUAL_ENV` environment variable"),
|
Self::VirtualEnvVar => f.write_str("`VIRTUAL_ENV` environment variable"),
|
||||||
Self::Derived => f.write_str("derived `sys.prefix` path"),
|
Self::Derived => f.write_str("derived `sys.prefix` path"),
|
||||||
|
Self::LocalVenv => f.write_str("local virtual environment"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue