mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-24 05:26:23 +00:00
[red-knot] Change venv discovery (#17099)
## Summary Rewrites the virtual env discovery to: * Only use of `System` APIs, this ensures that the discovery will also work when using a memory file system (testing or WASM) * Don't traverse ancestor directories. We're not convinced that this is necessary. Let's wait until someone shows us a use case where it is needed * Start from the project root and not from the current working directory. This ensures that Red Knot picks up the right venv even when using `knot --project ../other-dir` ## Test Plan Existing tests, @ntBre tested that the `file_watching` tests no longer pick up his virtual env in a parent directory
This commit is contained in:
parent
4a6fa5fc27
commit
a1535fbdbd
3 changed files with 14 additions and 20 deletions
|
@ -121,7 +121,7 @@ impl Options {
|
|||
.ok()
|
||||
.map(PythonPath::from_virtual_env_var)
|
||||
})
|
||||
.unwrap_or(PythonPath::Discover),
|
||||
.unwrap_or_else(|| PythonPath::Discover(project_root.to_path_buf())),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -133,20 +133,13 @@ pub(crate) fn search_paths(db: &dyn Db) -> SearchPathIterator {
|
|||
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()?;
|
||||
/// Searches for a `.venv` directory in `project_root` that contains a `pyvenv.cfg` file.
|
||||
fn discover_venv_in(system: &dyn System, project_root: &SystemPath) -> Option<SystemPathBuf> {
|
||||
let virtual_env_directory = project_root.join(".venv");
|
||||
|
||||
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
|
||||
system
|
||||
.is_file(&virtual_env_directory.join("pyvenv.cfg"))
|
||||
.then_some(virtual_env_directory)
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
|
@ -251,15 +244,15 @@ impl SearchPaths {
|
|||
.and_then(|venv| venv.site_packages_directories(system))?
|
||||
}
|
||||
|
||||
PythonPath::Discover => {
|
||||
tracing::debug!("Discovering virtual environment");
|
||||
let virtual_env_path = virtual_env_from_working_dir();
|
||||
PythonPath::Discover(root) => {
|
||||
tracing::debug!("Discovering virtual environment in `{root}`");
|
||||
let virtual_env_path = discover_venv_in(db.system(), root);
|
||||
if let Some(virtual_env_path) = virtual_env_path {
|
||||
tracing::debug!("Found `.venv` folder at '{}'", 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 '{}': {}",
|
||||
"Ignoring automatically detected virtual environment at `{}`: {}",
|
||||
virtual_env_path,
|
||||
error
|
||||
);
|
||||
|
|
|
@ -145,7 +145,8 @@ pub enum PythonPath {
|
|||
/// [`sys.prefix`]: https://docs.python.org/3/library/sys.html#sys.prefix
|
||||
SysPrefix(SystemPathBuf, SysPrefixPathOrigin),
|
||||
|
||||
Discover,
|
||||
/// Tries to discover a virtual environment in the given path.
|
||||
Discover(SystemPathBuf),
|
||||
|
||||
/// Resolved site packages paths.
|
||||
///
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue