Skip to content

Commit a99a458

Browse files
Eagerly validate search paths (#12783)
Co-authored-by: Alex Waygood <[email protected]>
1 parent fabf19f commit a99a458

File tree

15 files changed

+343
-265
lines changed

15 files changed

+343
-265
lines changed

crates/red_knot/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ fn run() -> anyhow::Result<ExitStatus> {
184184

185185
// TODO: Use the `program_settings` to compute the key for the database's persistent
186186
// cache and load the cache if it exists.
187-
let mut db = RootDatabase::new(workspace_metadata, program_settings, system);
187+
let mut db = RootDatabase::new(workspace_metadata, program_settings, system)?;
188188

189189
let (main_loop, main_loop_cancellation_token) = MainLoop::new();
190190

crates/red_knot/tests/file_watching.rs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use std::io::Write;
44
use std::time::Duration;
55

66
use anyhow::{anyhow, Context};
7-
use salsa::Setter;
87

98
use red_knot_python_semantic::{
109
resolve_module, ModuleName, Program, ProgramSettings, PythonVersion, SearchPathSettings,
@@ -26,6 +25,7 @@ struct TestCase {
2625
/// We need to hold on to it in the test case or the temp files get deleted.
2726
_temp_dir: tempfile::TempDir,
2827
root_dir: SystemPathBuf,
28+
search_path_settings: SearchPathSettings,
2929
}
3030

3131
impl TestCase {
@@ -108,18 +108,20 @@ impl TestCase {
108108
fn update_search_path_settings(
109109
&mut self,
110110
f: impl FnOnce(&SearchPathSettings) -> SearchPathSettings,
111-
) {
111+
) -> anyhow::Result<()> {
112112
let program = Program::get(self.db());
113-
let search_path_settings = program.search_paths(self.db());
114113

115-
let new_settings = f(search_path_settings);
114+
let new_settings = f(&self.search_path_settings);
116115

117-
program.set_search_paths(&mut self.db).to(new_settings);
116+
program.update_search_paths(&mut self.db, new_settings.clone())?;
117+
self.search_path_settings = new_settings;
118118

119119
if let Some(watcher) = &mut self.watcher {
120120
watcher.update(&self.db);
121121
assert!(!watcher.has_errored_paths());
122122
}
123+
124+
Ok(())
123125
}
124126

125127
fn collect_package_files(&self, path: &SystemPath) -> Vec<File> {
@@ -221,24 +223,24 @@ where
221223
let system = OsSystem::new(&workspace_path);
222224

223225
let workspace = WorkspaceMetadata::from_path(&workspace_path, &system)?;
224-
let search_paths = create_search_paths(&root_path, workspace.root());
226+
let search_path_settings = create_search_paths(&root_path, workspace.root());
225227

226-
for path in search_paths
228+
for path in search_path_settings
227229
.extra_paths
228230
.iter()
229-
.chain(search_paths.site_packages.iter())
230-
.chain(search_paths.custom_typeshed.iter())
231+
.chain(search_path_settings.site_packages.iter())
232+
.chain(search_path_settings.custom_typeshed.iter())
231233
{
232234
std::fs::create_dir_all(path.as_std_path())
233235
.with_context(|| format!("Failed to create search path '{path}'"))?;
234236
}
235237

236238
let settings = ProgramSettings {
237239
target_version: PythonVersion::default(),
238-
search_paths,
240+
search_paths: search_path_settings.clone(),
239241
};
240242

241-
let db = RootDatabase::new(workspace, settings, system);
243+
let db = RootDatabase::new(workspace, settings, system)?;
242244

243245
let (sender, receiver) = crossbeam::channel::unbounded();
244246
let watcher = directory_watcher(move |events| sender.send(events).unwrap())
@@ -253,6 +255,7 @@ where
253255
watcher: Some(watcher),
254256
_temp_dir: temp_dir,
255257
root_dir: root_path,
258+
search_path_settings,
256259
};
257260

258261
// Sometimes the file watcher reports changes for events that happened before the watcher was started.
@@ -737,7 +740,8 @@ fn add_search_path() -> anyhow::Result<()> {
737740
case.update_search_path_settings(|settings| SearchPathSettings {
738741
site_packages: vec![site_packages.clone()],
739742
..settings.clone()
740-
});
743+
})
744+
.expect("Search path settings to be valid");
741745

742746
std::fs::write(site_packages.join("a.py").as_std_path(), "class A: ...")?;
743747

@@ -767,7 +771,8 @@ fn remove_search_path() -> anyhow::Result<()> {
767771
case.update_search_path_settings(|settings| SearchPathSettings {
768772
site_packages: vec![],
769773
..settings.clone()
770-
});
774+
})
775+
.expect("Search path settings to be valid");
771776

772777
std::fs::write(site_packages.join("a.py").as_std_path(), "class A: ...")?;
773778

crates/red_knot_python_semantic/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ ruff_python_ast = { workspace = true }
1717
ruff_python_stdlib = { workspace = true }
1818
ruff_text_size = { workspace = true }
1919

20+
anyhow = { workspace = true }
2021
bitflags = { workspace = true }
2122
camino = { workspace = true }
2223
compact_str = { workspace = true }
@@ -34,7 +35,7 @@ walkdir = { workspace = true }
3435
zip = { workspace = true, features = ["zstd", "deflate"] }
3536

3637
[dev-dependencies]
37-
ruff_db = { workspace = true, features = ["os", "testing"]}
38+
ruff_db = { workspace = true, features = ["os", "testing"] }
3839
ruff_python_parser = { workspace = true }
3940

4041
anyhow = { workspace = true }

crates/red_knot_python_semantic/src/module_resolver/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ use std::iter::FusedIterator;
22

33
pub(crate) use module::Module;
44
pub use resolver::resolve_module;
5+
pub(crate) use resolver::SearchPaths;
56
use ruff_db::system::SystemPath;
67
pub use typeshed::vendored_typeshed_stubs;
78

9+
use crate::module_resolver::resolver::search_paths;
810
use crate::Db;
9-
use resolver::{module_resolution_settings, SearchPathIterator};
11+
use resolver::SearchPathIterator;
1012

1113
mod module;
1214
mod path;
@@ -20,7 +22,7 @@ mod testing;
2022
/// Returns an iterator over all search paths pointing to a system path
2123
pub fn system_module_search_paths(db: &dyn Db) -> SystemModuleSearchPathsIter {
2224
SystemModuleSearchPathsIter {
23-
inner: module_resolution_settings(db).search_paths(db),
25+
inner: search_paths(db),
2426
}
2527
}
2628

0 commit comments

Comments
 (0)