Skip to content

Commit cdbd6a1

Browse files
yangdanny97meta-codesync[bot]
authored andcommitted
basic ipynb support for type checking
Summary: This is an absolute minimal implementation, s.t `pyrefly check <some ipynb file>` emits errors. The error positions are all wrong, because they used the concatenated file. This will be fixed later. Reviewed By: kinto0 Differential Revision: D85438479 fbshipit-source-id: 99e96b510b708770b16f7c83e7b92b0156f26359
1 parent 77f63bf commit cdbd6a1

File tree

16 files changed

+301
-27
lines changed

16 files changed

+301
-27
lines changed

Cargo.lock

Lines changed: 105 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/pyrefly_python/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ parse-display = "0.8.2"
1818
pathdiff = "0.2"
1919
pyrefly_util = { path = "../pyrefly_util" }
2020
regex = "1.11.1"
21+
ruff_notebook = { git = "https://github.com/astral-sh/ruff/", rev = "9bee8376a17401f9736b45fdefffb62edc2f1668" }
2122
ruff_python_ast = { git = "https://github.com/astral-sh/ruff/", rev = "9bee8376a17401f9736b45fdefffb62edc2f1668" }
2223
ruff_python_parser = { git = "https://github.com/astral-sh/ruff/", rev = "9bee8376a17401f9736b45fdefffb62edc2f1668" }
24+
ruff_source_file = { git = "https://github.com/astral-sh/ruff/", rev = "9bee8376a17401f9736b45fdefffb62edc2f1668" }
2325
ruff_text_size = { git = "https://github.com/astral-sh/ruff/", rev = "9bee8376a17401f9736b45fdefffb62edc2f1668" }
2426
serde = { version = "1.0.219", features = ["derive", "rc"] }
2527
starlark_map = "0.13.0"

crates/pyrefly_python/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ pub mod short_identifier;
3333
pub mod symbol_kind;
3434
pub mod sys_info;
3535

36-
/// Suffixes of python files that we can be processed.
37-
pub const PYTHON_EXTENSIONS: &[&str] = &["py", "pyi"];
36+
/// Suffixes of python files that can be processed.
37+
pub const PYTHON_EXTENSIONS: &[&str] = &["py", "pyi", "ipynb"];
3838

3939
/// Suffixes of compiled python modules
4040
pub const COMPILED_FILE_SUFFIXES: &[&str] = &["pyc", "pyx", "pyd"];

crates/pyrefly_python/src/module.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ use dupe::Dupe;
1111
use pyrefly_util::arc_id::ArcId;
1212
use pyrefly_util::lined_buffer::DisplayPos;
1313
use pyrefly_util::lined_buffer::DisplayRange;
14+
use pyrefly_util::lined_buffer::LineNumber;
1415
use pyrefly_util::lined_buffer::LinedBuffer;
16+
use ruff_notebook::Notebook;
17+
use ruff_source_file::OneIndexed;
1518
use ruff_text_size::TextRange;
1619
use ruff_text_size::TextSize;
1720

@@ -32,6 +35,7 @@ struct ModuleInner {
3235
ignore: Ignore,
3336
is_generated: bool,
3437
contents: LinedBuffer,
38+
notebook: Option<Box<Notebook>>,
3539
}
3640

3741
impl Module {
@@ -46,6 +50,22 @@ impl Module {
4650
ignore,
4751
is_generated,
4852
contents,
53+
notebook: None,
54+
}))
55+
}
56+
57+
pub fn new_notebook(name: ModuleName, path: ModulePath, notebook: Notebook) -> Self {
58+
let contents: Arc<String> = Arc::from(notebook.source_code().to_owned());
59+
let ignore = Ignore::new(&contents);
60+
let is_generated = contents.contains(GENERATED_TOKEN);
61+
let contents = LinedBuffer::new(contents);
62+
Self(ArcId::new(ModuleInner {
63+
name,
64+
path,
65+
ignore,
66+
is_generated,
67+
contents,
68+
notebook: Some(Box::new(notebook)),
4969
}))
5070
}
5171

@@ -87,6 +107,10 @@ impl Module {
87107
&self.0.path
88108
}
89109

110+
pub fn is_notebook(&self) -> bool {
111+
self.0.notebook.is_some()
112+
}
113+
90114
pub fn is_generated(&self) -> bool {
91115
self.0.is_generated
92116
}
@@ -116,6 +140,10 @@ impl Module {
116140
pub fn ignore(&self) -> &Ignore {
117141
&self.0.ignore
118142
}
143+
144+
pub fn notebook(&self) -> Option<&Notebook> {
145+
self.0.notebook.as_deref()
146+
}
119147
}
120148

121149
#[derive(Debug, Clone)]
@@ -129,3 +157,21 @@ impl TextRangeWithModule {
129157
Self { module, range }
130158
}
131159
}
160+
161+
/// Given a one-indexed row and column in the concatenated source,
162+
/// return the cell number, and the row/column in that cell.
163+
pub fn map_notebook_position(
164+
notebook: &Notebook,
165+
position: DisplayPos,
166+
) -> Option<(OneIndexed, DisplayPos)> {
167+
let index = notebook.index();
168+
let cell = index.cell(position.line.to_one_indexed())?;
169+
let cell_row = index
170+
.cell_row(position.line.to_one_indexed())
171+
.unwrap_or(OneIndexed::MIN);
172+
let display_pos = DisplayPos {
173+
line: LineNumber::from_one_indexed(cell_row),
174+
column: position.column,
175+
};
176+
Some((cell, display_pos))
177+
}

crates/pyrefly_python/src/module_name.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,9 @@ impl ModuleName {
208208
None => {}
209209
Some(file_name) => {
210210
let splits: Vec<&str> = file_name.rsplitn(2, '.').collect();
211-
if splits.len() != 2 || !(splits[0] == "py" || splits[0] == "pyi") {
211+
if splits.len() != 2
212+
|| !(splits[0] == "py" || splits[0] == "pyi" || splits[0] == "ipynb")
213+
{
212214
return Err(anyhow::anyhow!(PathConversionError::InvalidExtension {
213215
file_name: file_name.to_owned(),
214216
}));
@@ -417,8 +419,10 @@ mod tests {
417419
}
418420
assert_module_name("foo.py", "foo");
419421
assert_module_name("foo.pyi", "foo");
422+
assert_module_name("foo.ipynb", "foo");
420423
assert_module_name("foo/bar.py", "foo.bar");
421424
assert_module_name("foo/bar.pyi", "foo.bar");
425+
assert_module_name("foo/bar.ipynb", "foo.bar");
422426
assert_module_name("foo/bar/__init__.py", "foo.bar");
423427
assert_module_name("foo/bar/__init__.pyi", "foo.bar");
424428

crates/pyrefly_python/src/module_path.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ impl ModuleStyle {
9595
if path.extension() == Some("pyi".as_ref()) {
9696
ModuleStyle::Interface
9797
} else {
98+
// Both .py and .ipynb are executable
9899
ModuleStyle::Executable
99100
}
100101
}

crates/pyrefly_util/src/globs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ impl Glob {
142142
}
143143

144144
fn is_python_extension(ext: Option<&OsStr>) -> bool {
145-
ext.is_some_and(|e| e == "py" || e == "pyi" || e == "pyw")
145+
ext.is_some_and(|e| e == "py" || e == "pyi" || e == "pyw" || e == "ipynb")
146146
}
147147

148148
/// Returns true if the given file should be included in results.

crates/pyrefly_util/src/lined_buffer.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,11 @@ impl LineNumber {
227227
self.0.get() - 1
228228
}
229229

230-
fn to_one_indexed(self) -> OneIndexed {
230+
pub fn from_one_indexed(x: OneIndexed) -> Self {
231+
Self(NonZeroU32::new(x.get().try_into().unwrap()).unwrap())
232+
}
233+
234+
pub fn to_one_indexed(self) -> OneIndexed {
231235
OneIndexed::new(self.0.get() as usize).unwrap()
232236
}
233237

pyrefly/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ pyrefly_util = { path = "../crates/pyrefly_util" }
4242
rayon = "1.11.0"
4343
regex = "1.11.1"
4444
ruff_annotate_snippets = { git = "https://github.com/astral-sh/ruff/", rev = "9bee8376a17401f9736b45fdefffb62edc2f1668" }
45+
ruff_notebook = { git = "https://github.com/astral-sh/ruff/", rev = "9bee8376a17401f9736b45fdefffb62edc2f1668" }
4546
ruff_python_ast = { git = "https://github.com/astral-sh/ruff/", rev = "9bee8376a17401f9736b45fdefffb62edc2f1668", features = ["serde"] }
4647
ruff_python_parser = { git = "https://github.com/astral-sh/ruff/", rev = "9bee8376a17401f9736b45fdefffb62edc2f1668" }
4748
ruff_source_file = { git = "https://github.com/astral-sh/ruff/", rev = "9bee8376a17401f9736b45fdefffb62edc2f1668" }

0 commit comments

Comments
 (0)