Skip to content

Commit

Permalink
Store settings on WorkspaceMetadata
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaReiser committed Aug 15, 2024
1 parent 8d9263f commit a4c9afe
Show file tree
Hide file tree
Showing 16 changed files with 107 additions and 76 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions crates/red_knot/tests/file_watching.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,10 @@ impl TestCase {
) -> anyhow::Result<()> {
let program = Program::get(self.db());

let new_settings = configuration.to_settings(self.db.workspace().root(&self.db));
self.configuration.search_paths = configuration;
self.configuration.search_paths = configuration.clone();
let new_settings = configuration.into_settings(self.db.workspace().root(&self.db));

program.update_search_paths(&mut self.db, new_settings)?;
program.update_search_paths(&mut self.db, &new_settings)?;

if let Some(watcher) = &mut self.watcher {
watcher.update(&self.db);
Expand Down
5 changes: 4 additions & 1 deletion crates/red_knot_python_semantic/src/module_resolver/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,10 @@ impl fmt::Display for SearchPathValidationError {
write!(f, "The directory at {path} has no `stdlib/` subdirectory")
}
Self::FailedToReadVersionsFile { path, error } => {
write!(f, "Failed to read the '{path}' file: {error}")
write!(
f,
"Failed to read the custom typeshed versions file '{path}': {error}"
)
}
Self::VersionsParseError(underlying_error) => underlying_error.fmt(f),
SearchPathValidationError::SitePackagesDiscovery(error) => {
Expand Down
48 changes: 34 additions & 14 deletions crates/red_knot_python_semantic/src/module_resolver/resolver.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use rustc_hash::{FxBuildHasher, FxHashSet};
use std::borrow::Cow;
use std::iter::FusedIterator;

use rustc_hash::{FxBuildHasher, FxHashSet};
use std::ops::Deref;

use ruff_db::files::{File, FilePath, FileRootKind};
use ruff_db::system::{DirectoryEntry, System, SystemPath, SystemPathBuf};
Expand Down Expand Up @@ -136,7 +136,7 @@ pub(crate) struct SearchPaths {
/// for the first `site-packages` path
site_packages: Vec<SearchPath>,

typeshed_versions: Cow<'static, TypeshedVersions>,
typeshed_versions: Typeshed,
}

impl SearchPaths {
Expand All @@ -148,10 +148,12 @@ impl SearchPaths {
/// [module resolution order]: https://typing.readthedocs.io/en/latest/spec/distributing.html#import-resolution-ordering
pub(crate) fn from_settings(
db: &dyn Db,
settings: SearchPathSettings,
settings: &SearchPathSettings,
) -> Result<Self, SearchPathValidationError> {
fn canonicalize(path: SystemPathBuf, system: &dyn System) -> SystemPathBuf {
system.canonicalize_path(&path).unwrap_or(path)
fn canonicalize(path: &SystemPath, system: &dyn System) -> SystemPathBuf {
system
.canonicalize_path(path)
.unwrap_or_else(|_| path.to_path_buf())
}

let SearchPathSettings {
Expand All @@ -175,7 +177,7 @@ impl SearchPaths {
}

tracing::debug!("Adding search path '{src_root}'");
static_paths.push(SearchPath::first_party(system, src_root)?);
static_paths.push(SearchPath::first_party(system, src_root.to_path_buf())?);

let (typeshed_versions, stdlib_path) = if let Some(custom_typeshed) = custom_typeshed {
let custom_typeshed = canonicalize(custom_typeshed, system);
Expand All @@ -200,11 +202,11 @@ impl SearchPaths {

let search_path = SearchPath::custom_stdlib(db, &custom_typeshed)?;

(Cow::Owned(parsed), search_path)
(Typeshed::Custom(parsed), search_path)
} else {
tracing::debug!("Using vendored stdlib");
(
Cow::Borrowed(vendored_typeshed_versions()),
Typeshed::Vendored(vendored_typeshed_versions()),
SearchPath::vendored_stdlib(),
)
};
Expand All @@ -214,14 +216,15 @@ impl SearchPaths {
let site_packages_paths = match site_packages_paths {
SitePackages::Derived { venv_path } => VirtualEnvironment::new(venv_path, system)
.and_then(|venv| venv.site_packages_directories(system))?,
SitePackages::Known(paths) => paths,
SitePackages::Known(paths) => paths
.iter()
.map(|path| canonicalize(path, system))
.collect(),
};

let mut site_packages: Vec<_> = Vec::with_capacity(site_packages_paths.len());

for path in site_packages_paths {
let path = canonicalize(path, system);

tracing::debug!("Adding site-package path '{path}'");
files.try_add_root(db.upcast(), &path, FileRootKind::LibrarySearchPath);
site_packages.push(SearchPath::site_packages(system, path)?);
Expand Down Expand Up @@ -276,6 +279,23 @@ impl SearchPaths {
}
}

#[derive(Debug, PartialEq, Eq)]
enum Typeshed {
Vendored(&'static TypeshedVersions),
Custom(TypeshedVersions),
}

impl Deref for Typeshed {
type Target = TypeshedVersions;

fn deref(&self) -> &Self::Target {
match self {
Typeshed::Vendored(versions) => versions,
Typeshed::Custom(versions) => versions,
}
}
}

/// Collect all dynamic search paths. For each `site-packages` path:
/// - Collect that `site-packages` path
/// - Collect any search paths listed in `.pth` files in that `site-packages` directory
Expand Down Expand Up @@ -1254,7 +1274,7 @@ mod tests {

Program::from_settings(
&db,
ProgramSettings {
&ProgramSettings {
target_version: PythonVersion::PY38,
search_paths: SearchPathSettings {
extra_paths: vec![],
Expand Down Expand Up @@ -1759,7 +1779,7 @@ not_a_directory

Program::from_settings(
&db,
ProgramSettings {
&ProgramSettings {
target_version: PythonVersion::default(),
search_paths: SearchPathSettings {
extra_paths: vec![],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ impl TestCaseBuilder<MockedTypeshed> {

Program::from_settings(
&db,
ProgramSettings {
&ProgramSettings {
target_version,
search_paths: SearchPathSettings {
extra_paths: vec![],
Expand Down Expand Up @@ -281,10 +281,9 @@ impl TestCaseBuilder<VendoredTypeshed> {

Program::from_settings(
&db,
ProgramSettings {
&ProgramSettings {
target_version,
search_paths: SearchPathSettings {
src_root: src.clone(),
site_packages: SitePackages::Known(vec![site_packages.clone()]),
..SearchPathSettings::new(src.clone())
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ impl fmt::Display for TypeshedVersionsParseErrorKind {
}
}

#[derive(Debug, PartialEq, Eq, Clone)]
#[derive(Debug, PartialEq, Eq)]
pub(crate) struct TypeshedVersions(FxHashMap<ModuleName, PyVersionRange>);

impl TypeshedVersions {
Expand Down
6 changes: 3 additions & 3 deletions crates/red_knot_python_semantic/src/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub struct Program {
}

impl Program {
pub fn from_settings(db: &dyn Db, settings: ProgramSettings) -> anyhow::Result<Self> {
pub fn from_settings(db: &dyn Db, settings: &ProgramSettings) -> anyhow::Result<Self> {
let ProgramSettings {
target_version,
search_paths,
Expand All @@ -36,7 +36,7 @@ impl Program {
pub fn update_search_paths(
self,
db: &mut dyn Db,
search_path_settings: SearchPathSettings,
search_path_settings: &SearchPathSettings,
) -> anyhow::Result<()> {
let search_paths = SearchPaths::from_settings(db, search_path_settings)?;

Expand All @@ -53,7 +53,7 @@ impl Program {
}
}

#[derive(Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ProgramSettings {
pub target_version: PythonVersion,
pub search_paths: SearchPathSettings,
Expand Down
2 changes: 1 addition & 1 deletion crates/red_knot_python_semantic/src/semantic_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ mod tests {

Program::from_settings(
&db,
ProgramSettings {
&ProgramSettings {
target_version: PythonVersion::default(),
search_paths: SearchPathSettings::new(SystemPathBuf::from("/src")),
},
Expand Down
4 changes: 2 additions & 2 deletions crates/red_knot_python_semantic/src/types/infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1599,7 +1599,7 @@ mod tests {

Program::from_settings(
&db,
ProgramSettings {
&ProgramSettings {
target_version: PythonVersion::default(),
search_paths: SearchPathSettings::new(src_root),
},
Expand All @@ -1621,7 +1621,7 @@ mod tests {

Program::from_settings(
&db,
ProgramSettings {
&ProgramSettings {
target_version: PythonVersion::default(),
search_paths: SearchPathSettings {
custom_typeshed: Some(SystemPathBuf::from(typeshed)),
Expand Down
1 change: 0 additions & 1 deletion crates/red_knot_workspace/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ crossbeam = { workspace = true }
notify = { workspace = true }
rustc-hash = { workspace = true }
salsa = { workspace = true }
thiserror = { workspace = true }
tracing = { workspace = true }

[dev-dependencies]
Expand Down
8 changes: 3 additions & 5 deletions crates/red_knot_workspace/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,18 @@ impl RootDatabase {
where
S: System + 'static + Send + Sync + RefUnwindSafe,
{
let program_settings = workspace.to_program_settings(workspace.root());

let mut db = Self {
workspace: None,
storage: salsa::Storage::default(),
files: Files::default(),
system: Arc::new(system),
};

let workspace = Workspace::from_metadata(&db, workspace);
// Initialize the `Program` singleton
Program::from_settings(&db, program_settings)?;
Program::from_settings(&db, workspace.settings().program())?;

db.workspace = Some(Workspace::from_metadata(&db, workspace));

db.workspace = Some(workspace);
Ok(db)
}

Expand Down
8 changes: 3 additions & 5 deletions crates/red_knot_workspace/src/db/changes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,11 +156,9 @@ impl RootDatabase {

return;
} else if custom_stdlib_change {
let search_path_configuration = workspace.search_path_configuration(self);

let search_path_settings = search_path_configuration.to_settings(&workspace_path);
if let Err(error) = program.update_search_paths(self, search_path_settings) {
tracing::error!("Failed to apply to set the new search paths: {error}");
let search_paths = workspace.search_path_settings(self).clone();
if let Err(error) = program.update_search_paths(self, &search_paths) {
tracing::error!("Failed to set the new search paths: {error}");
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/red_knot_workspace/src/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ mod tests {

Program::from_settings(
&db,
ProgramSettings {
&ProgramSettings {
target_version: PythonVersion::default(),
search_paths: SearchPathSettings::new(src_root),
},
Expand Down
22 changes: 13 additions & 9 deletions crates/red_knot_workspace/src/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use rustc_hash::{FxBuildHasher, FxHashSet};
use salsa::{Durability, Setter as _};

pub use metadata::{PackageMetadata, WorkspaceMetadata};
use red_knot_python_semantic::SearchPathSettings;
use ruff_db::source::{source_text, SourceDiagnostic};
use ruff_db::{
files::{system_path_to_file, File},
Expand All @@ -12,7 +13,6 @@ use ruff_db::{
use ruff_python_ast::{name::Name, PySourceType};

use crate::workspace::files::{Index, IndexedFiles, PackageFiles};
use crate::workspace::settings::SearchPathConfiguration;
use crate::{
db::Db,
lint::{lint_semantic, lint_syntax, Diagnostics},
Expand Down Expand Up @@ -84,7 +84,7 @@ pub struct Workspace {

/// The unresolved search path configuration.
#[return_ref]
pub search_path_configuration: SearchPathConfiguration,
pub search_path_settings: SearchPathSettings,
}

/// A first-party package in a workspace.
Expand Down Expand Up @@ -113,10 +113,14 @@ impl Workspace {
packages.insert(package.root.clone(), Package::from_metadata(db, package));
}

Workspace::builder(metadata.root, packages, metadata.configuration.search_paths)
.durability(Durability::MEDIUM)
.open_fileset_durability(Durability::LOW)
.new(db)
Workspace::builder(
metadata.root,
packages,
metadata.settings.program.search_paths,
)
.durability(Durability::MEDIUM)
.open_fileset_durability(Durability::LOW)
.new(db)
}

pub fn root(self, db: &dyn Db) -> &SystemPath {
Expand Down Expand Up @@ -147,9 +151,9 @@ impl Workspace {
new_packages.insert(path, package);
}

if &metadata.configuration.search_paths != self.search_path_configuration(db) {
self.set_search_path_configuration(db)
.to(metadata.configuration.search_paths);
if &metadata.settings.program.search_paths != self.search_path_settings(db) {
self.set_search_path_settings(db)
.to(metadata.settings.program.search_paths);
}

self.set_package_tree(db)
Expand Down
Loading

0 comments on commit a4c9afe

Please sign in to comment.