[red-knot] Reload notebook on file change (#12361)

This commit is contained in:
Micha Reiser 2024-07-17 14:23:48 +02:00 committed by GitHub
parent 6e0cbe0f35
commit 79b535587b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 27 additions and 10 deletions

View file

@ -103,7 +103,7 @@ fn lint_unresolved_imports(context: &SemanticLintContext, import: AnyImportRef)
for alias in &import.names {
let ty = alias.ty(&context.semantic);
if ty.is_unknown() {
if ty.is_unbound() {
context.push_diagnostic(format!("Unresolved import '{}'", &alias.name));
}
}
@ -112,7 +112,7 @@ fn lint_unresolved_imports(context: &SemanticLintContext, import: AnyImportRef)
for alias in &import.names {
let ty = alias.ty(&context.semantic);
if ty.is_unknown() {
if ty.is_unbound() {
context.push_diagnostic(format!("Unresolved import '{}'", &alias.name));
}
}

View file

@ -3,13 +3,13 @@ use std::sync::Arc;
use countme::Count;
use dashmap::mapref::entry::Entry;
pub use path::FilePath;
use crate::file_revision::FileRevision;
use crate::files::private::FileStatus;
use crate::system::SystemPath;
use crate::vendored::VendoredPath;
use crate::{Db, FxDashMap};
pub use path::FilePath;
use ruff_notebook::{Notebook, NotebookError};
mod path;
@ -182,11 +182,7 @@ impl File {
/// Reads the content of the file into a [`String`].
///
/// Reading the same file multiple times isn't guaranteed to return the same content. It's possible
/// that the file has been modified in between the reads. It's even possible that a file that
/// is considered to exist has been deleted in the meantime. If this happens, then the method returns
/// an empty string, which is the closest to the content that the file contains now. Returning
/// an empty string shouldn't be a problem because the query will be re-executed as soon as the
/// changes are applied to the database.
/// that the file has been modified in between the reads.
pub fn read_to_string(&self, db: &dyn Db) -> crate::system::Result<String> {
let path = self.path(db);
@ -201,6 +197,27 @@ impl File {
}
}
/// Reads the content of the file into a [`Notebook`].
///
/// Reading the same file multiple times isn't guaranteed to return the same content. It's possible
/// that the file has been modified in between the reads.
pub fn read_to_notebook(&self, db: &dyn Db) -> Result<Notebook, NotebookError> {
let path = self.path(db);
match path {
FilePath::System(system) => {
// Add a dependency on the revision to ensure the operation gets re-executed when the file changes.
let _ = self.revision(db);
db.system().read_to_notebook(system)
}
FilePath::Vendored(_) => Err(NotebookError::Io(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
"Reading a notebook from the vendored file system is not supported.",
))),
}
}
/// Refreshes the file metadata by querying the file system if needed.
/// TODO: The API should instead take all observed changes from the file system directly
/// and then apply the VfsFile status accordingly. But for now, this is sufficient.

View file

@ -21,7 +21,7 @@ pub fn source_text(db: &dyn Db, file: File) -> SourceText {
PySourceType::try_from_extension(extension) == Some(PySourceType::Ipynb)
}) {
// TODO(micha): Proper error handling and emit a diagnostic. Tackle it together with `source_text`.
let notebook = db.system().read_to_notebook(path).unwrap_or_else(|error| {
let notebook = file.read_to_notebook(db).unwrap_or_else(|error| {
tracing::error!("Failed to load notebook: {error}");
Notebook::empty()
});