Skip to content

Commit 1005dcc

Browse files
Merge pull request RustPython#1631 from youknowone/syntax-error
implement SyntaxError attributes
2 parents bd94120 + 2e54f9a commit 1005dcc

File tree

6 files changed

+47
-6
lines changed

6 files changed

+47
-6
lines changed

compiler/src/compile.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,17 +63,21 @@ pub fn compile(
6363
match mode {
6464
Mode::Exec => {
6565
let ast = parser::parse_program(source)?;
66-
compile_program(ast, source_path, optimize)
66+
compile_program(ast, source_path.clone(), optimize)
6767
}
6868
Mode::Eval => {
6969
let statement = parser::parse_statement(source)?;
70-
compile_statement_eval(statement, source_path, optimize)
70+
compile_statement_eval(statement, source_path.clone(), optimize)
7171
}
7272
Mode::Single => {
7373
let ast = parser::parse_program(source)?;
74-
compile_program_single(ast, source_path, optimize)
74+
compile_program_single(ast, source_path.clone(), optimize)
7575
}
7676
}
77+
.map_err(|mut err| {
78+
err.update_source_path(&source_path);
79+
err
80+
})
7781
}
7882

7983
/// A helper function for the shared code of the different compile functions
@@ -258,6 +262,7 @@ impl<O: OutputStream> Compiler<O> {
258262
statement: None,
259263
error: CompileErrorType::ExpectExpr,
260264
location: statement.location.clone(),
265+
source_path: None,
261266
});
262267
}
263268
}
@@ -537,6 +542,7 @@ impl<O: OutputStream> Compiler<O> {
537542
statement: None,
538543
error: CompileErrorType::InvalidBreak,
539544
location: statement.location.clone(),
545+
source_path: None,
540546
});
541547
}
542548
self.emit(Instruction::Break);
@@ -547,6 +553,7 @@ impl<O: OutputStream> Compiler<O> {
547553
statement: None,
548554
error: CompileErrorType::InvalidContinue,
549555
location: statement.location.clone(),
556+
source_path: None,
550557
});
551558
}
552559
self.emit(Instruction::Continue);
@@ -557,6 +564,7 @@ impl<O: OutputStream> Compiler<O> {
557564
statement: None,
558565
error: CompileErrorType::InvalidReturn,
559566
location: statement.location.clone(),
567+
source_path: None,
560568
});
561569
}
562570
match value {
@@ -635,6 +643,7 @@ impl<O: OutputStream> Compiler<O> {
635643
statement: None,
636644
error: CompileErrorType::Delete(expression.name()),
637645
location: self.current_source_location.clone(),
646+
source_path: None,
638647
});
639648
}
640649
}
@@ -1339,6 +1348,7 @@ impl<O: OutputStream> Compiler<O> {
13391348
statement: None,
13401349
error: CompileErrorType::StarArgs,
13411350
location: self.current_source_location.clone(),
1351+
source_path: None,
13421352
});
13431353
} else {
13441354
seen_star = true;
@@ -1369,6 +1379,7 @@ impl<O: OutputStream> Compiler<O> {
13691379
statement: None,
13701380
error: CompileErrorType::Assign(target.name()),
13711381
location: self.current_source_location.clone(),
1382+
source_path: None,
13721383
});
13731384
}
13741385
}
@@ -1654,6 +1665,7 @@ impl<O: OutputStream> Compiler<O> {
16541665
statement: Option::None,
16551666
error: CompileErrorType::InvalidYield,
16561667
location: self.current_source_location.clone(),
1668+
source_path: Option::None,
16571669
});
16581670
}
16591671
self.mark_generator();
@@ -1751,6 +1763,7 @@ impl<O: OutputStream> Compiler<O> {
17511763
"Invalid starred expression",
17521764
)),
17531765
location: self.current_source_location.clone(),
1766+
source_path: Option::None,
17541767
});
17551768
}
17561769
IfExpression { test, body, orelse } => {

compiler/src/error.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,18 @@ pub struct CompileError {
1010
pub statement: Option<String>,
1111
pub error: CompileErrorType,
1212
pub location: Location,
13+
pub source_path: Option<String>,
1314
}
1415

1516
impl CompileError {
1617
pub fn update_statement_info(&mut self, statement: String) {
1718
self.statement = Some(statement);
1819
}
20+
21+
pub fn update_source_path(&mut self, source_path: &str) {
22+
debug_assert!(self.source_path.is_none());
23+
self.source_path = Some(source_path.to_owned());
24+
}
1925
}
2026

2127
impl From<ParseError> for CompileError {
@@ -24,6 +30,7 @@ impl From<ParseError> for CompileError {
2430
statement: None,
2531
error: CompileErrorType::Parse(error.error),
2632
location: error.location,
33+
source_path: None,
2734
}
2835
}
2936
}

compiler/src/symboltable.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ impl From<SymbolTableError> for CompileError {
145145
statement: None,
146146
error: CompileErrorType::SyntaxError(error.error),
147147
location: error.location,
148+
source_path: None,
148149
}
149150
}
150151
}

vm/src/exceptions.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,14 @@ pub fn init(ctx: &PyContext) {
565565
"__repr__" => ctx.new_rustfunc(exception_repr),
566566
});
567567

568+
extend_class!(ctx, &excs.syntax_error, {
569+
"msg" => ctx.new_property(make_arg_getter(0)),
570+
"filename" => ctx.new_property(make_arg_getter(1)),
571+
"lineno" => ctx.new_property(make_arg_getter(2)),
572+
"offset" => ctx.new_property(make_arg_getter(3)),
573+
"text" => ctx.new_property(make_arg_getter(4)),
574+
});
575+
568576
extend_class!(ctx, &excs.import_error, {
569577
"__init__" => ctx.new_rustfunc(import_error_init)
570578
});

vm/src/stdlib/symtable.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,18 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
2525
/// See docs: https://docs.python.org/3/library/symtable.html?highlight=symtable#symtable.symtable
2626
fn symtable_symtable(
2727
source: PyStringRef,
28-
_filename: PyStringRef,
28+
filename: PyStringRef,
2929
mode: PyStringRef,
3030
vm: &VirtualMachine,
3131
) -> PyResult<PySymbolTableRef> {
3232
let mode = mode
3333
.as_str()
3434
.parse::<compile::Mode>()
3535
.map_err(|err| vm.new_value_error(err.to_string()))?;
36-
let symtable =
37-
source_to_symtable(source.as_str(), mode).map_err(|err| vm.new_syntax_error(&err))?;
36+
let symtable = source_to_symtable(source.as_str(), mode).map_err(|mut err| {
37+
err.update_source_path(filename.as_str());
38+
vm.new_syntax_error(&err)
39+
})?;
3840

3941
let py_symbol_table = to_py_symbol_table(symtable);
4042
Ok(py_symbol_table.into_ref(vm))

vm/src/vm.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,17 @@ impl VirtualMachine {
409409
};
410410
let syntax_error = self.new_exception(syntax_error_type, error.to_string());
411411
let lineno = self.new_int(error.location.row());
412+
let offset = self.new_int(error.location.column());
412413
self.set_attr(&syntax_error, "lineno", lineno).unwrap();
414+
self.set_attr(&syntax_error, "offset", offset).unwrap();
415+
if let Some(v) = error.statement.as_ref() {
416+
self.set_attr(&syntax_error, "text", self.new_str(v.to_owned()))
417+
.unwrap();
418+
}
419+
if let Some(path) = error.source_path.as_ref() {
420+
self.set_attr(&syntax_error, "filename", self.new_str(path.to_owned()))
421+
.unwrap();
422+
}
413423
syntax_error
414424
}
415425

0 commit comments

Comments
 (0)