Skip to content

Commit e8f5f99

Browse files
committed
Return syntax error
1 parent b9ad305 commit e8f5f99

5 files changed

Lines changed: 31 additions & 6 deletions

File tree

rust/src/errors.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
use crate::exceptions::{InvalidModuleExpression, ModuleNotPresent, NoSuchContainer};
1+
use crate::exceptions::{InvalidModuleExpression, ModuleNotPresent, NoSuchContainer, ParseError};
22
use pyo3::exceptions::PyValueError;
33
use pyo3::PyErr;
4+
use ruff_python_parser::ParseError as RuffParseError;
45
use thiserror::Error;
56

67
#[derive(Debug, Error)]
@@ -16,6 +17,14 @@ pub enum GrimpError {
1617

1718
#[error("{0} is not a valid module expression.")]
1819
InvalidModuleExpression(String),
20+
21+
#[error("Error parsing python code (line {line_number}, text {text}).")]
22+
ParseError {
23+
line_number: usize,
24+
text: String,
25+
#[source]
26+
parse_error: RuffParseError,
27+
},
1928
}
2029

2130
pub type GrimpResult<T> = Result<T, GrimpError>;
@@ -30,6 +39,7 @@ impl From<GrimpError> for PyErr {
3039
GrimpError::InvalidModuleExpression(_) => {
3140
InvalidModuleExpression::new_err(value.to_string())
3241
}
42+
GrimpError::ParseError { .. } => ParseError::new_err(value.to_string()),
3343
}
3444
}
3545
}

rust/src/exceptions.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ create_exception!(
77
InvalidModuleExpression,
88
pyo3::exceptions::PyException
99
);
10+
create_exception!(_rustgrimp, ParseError, pyo3::exceptions::PyException);

rust/src/import_parsing.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::errors::GrimpResult;
1+
use crate::errors::{GrimpError, GrimpResult};
22
use ruff_python_ast::statement_visitor::{walk_body, walk_stmt, StatementVisitor};
33
use ruff_python_ast::{Expr, Stmt};
44
use ruff_python_parser::parse_module;
@@ -73,11 +73,22 @@ pub fn parse_imports_from_code(code: &str) -> GrimpResult<Vec<ImportedObject>> {
7373
fn parse_imports_from_code_without_line_contents(
7474
code: &str,
7575
) -> GrimpResult<Vec<ImportedObjectWithoutLineContents>> {
76-
let ast = parse_module(code).expect("failed to parse python code");
77-
7876
let line_index = LineIndex::from_source_text(code);
7977
let source_code = SourceCode::new(code, &line_index);
8078

79+
let ast = match parse_module(code) {
80+
Ok(ast) => ast,
81+
Err(e) => {
82+
let line_number = source_code.line_index(e.location.start()).get();
83+
let text = source_code.slice(e.location);
84+
Err(GrimpError::ParseError {
85+
line_number,
86+
text: text.to_owned(),
87+
parse_error: e,
88+
})?
89+
}
90+
};
91+
8192
let mut visitor = Visitor::new(source_code);
8293
walk_body(&mut visitor, &ast.syntax().body);
8394

rust/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ pub mod import_parsing;
55
pub mod module_expressions;
66

77
use crate::errors::{GrimpError, GrimpResult};
8-
use crate::exceptions::{InvalidModuleExpression, ModuleNotPresent, NoSuchContainer};
8+
use crate::exceptions::{InvalidModuleExpression, ModuleNotPresent, NoSuchContainer, ParseError};
99
use crate::graph::higher_order_queries::Level;
1010
use crate::graph::{Graph, Module, ModuleIterator, ModuleTokenIterator};
1111
use crate::module_expressions::ModuleExpression;
@@ -29,6 +29,7 @@ fn _rustgrimp(py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
2929
"InvalidModuleExpression",
3030
py.get_type::<InvalidModuleExpression>(),
3131
)?;
32+
m.add("ParseError", py.get_type::<ParseError>())?;
3233
Ok(())
3334
}
3435

src/grimp/adaptors/importscanner.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ def scan_for_imports(
5050

5151
try:
5252
imported_objects = self._get_raw_imported_objects(module_contents)
53-
except SyntaxError as e:
53+
except rust.ParseError as e:
54+
# TODO What to do with the rust.ParseError?
55+
# TODO The line number and text are part of str(e), but is there a nice way to get them?
5456
raise exceptions.SourceSyntaxError(
5557
filename=module_filename,
5658
lineno=e.lineno,

0 commit comments

Comments
 (0)