Skip to content

Commit 6f645d6

Browse files
[syntax-errors] nonlocal declaration at module level
The existing inline tests for nonlocal declaration parsing are no longer valid, hence we convert them to integration tests after enclosing in a scope.
1 parent 9b5fe51 commit 6f645d6

14 files changed

+180
-20
lines changed

crates/ruff_linter/src/checkers/ast/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,8 @@ impl SemanticSyntaxContext for Checker<'_> {
619619
| SemanticSyntaxErrorKind::DuplicateMatchKey(_)
620620
| SemanticSyntaxErrorKind::DuplicateMatchClassAttribute(_)
621621
| SemanticSyntaxErrorKind::InvalidStarExpression
622-
| SemanticSyntaxErrorKind::AsyncComprehensionOutsideAsyncFunction(_) => {
622+
| SemanticSyntaxErrorKind::AsyncComprehensionOutsideAsyncFunction(_)
623+
| SemanticSyntaxErrorKind::NonlocalDeclarationAtModuleLevel => {
623624
if self.settings.preview.is_enabled() {
624625
self.semantic_errors.borrow_mut().push(error);
625626
}

crates/ruff_linter/src/linter.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,6 +1040,50 @@ mod tests {
10401040
assert_messages!(snapshot, messages);
10411041
}
10421042

1043+
#[test_case(
1044+
"trailing_comma",
1045+
"
1046+
def f():
1047+
nonlocal ,
1048+
nonlocal x,
1049+
nonlocal x, y,
1050+
"
1051+
)]
1052+
#[test_case(
1053+
"expression",
1054+
"
1055+
def f():
1056+
nonlocal x + 1
1057+
"
1058+
)]
1059+
#[test_case(
1060+
"empty",
1061+
"
1062+
def f():
1063+
nonlocal
1064+
"
1065+
)]
1066+
#[test_case(
1067+
"correct",
1068+
"
1069+
def f():
1070+
nonlocal x
1071+
nonlocal x, y, z
1072+
"
1073+
)]
1074+
fn test_nonlocal_declarations(name: &str, contents: &str) {
1075+
let snapshot = format!("nonlocal_declaration_{name}");
1076+
let messages = test_snippet_syntax_errors(
1077+
contents,
1078+
&settings::LinterSettings {
1079+
rules: settings::rule_table::RuleTable::empty(),
1080+
preview: settings::types::PreviewMode::Enabled,
1081+
..Default::default()
1082+
},
1083+
);
1084+
assert_messages!(snapshot, messages);
1085+
}
1086+
10431087
#[test_case(PythonVersion::PY310)]
10441088
#[test_case(PythonVersion::PY311)]
10451089
fn test_async_comprehension_notebook(python_version: PythonVersion) -> Result<()> {
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
source: crates/ruff_linter/src/linter.rs
3+
---
4+
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
source: crates/ruff_linter/src/linter.rs
3+
---
4+
<filename>:3:13: SyntaxError: Nonlocal statement must have at least one name
5+
|
6+
2 | def f():
7+
3 | nonlocal
8+
| ^
9+
|
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
source: crates/ruff_linter/src/linter.rs
3+
---
4+
<filename>:3:16: SyntaxError: Simple statements must be separated by newlines or semicolons
5+
|
6+
2 | def f():
7+
3 | nonlocal x + 1
8+
| ^
9+
|
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
---
2+
source: crates/ruff_linter/src/linter.rs
3+
---
4+
<filename>:3:14: SyntaxError: Expected an identifier
5+
|
6+
2 | def f():
7+
3 | nonlocal ,
8+
| ^
9+
4 | nonlocal x,
10+
5 | nonlocal x, y,
11+
|
12+
13+
<filename>:3:15: SyntaxError: Nonlocal statement must have at least one name
14+
|
15+
2 | def f():
16+
3 | nonlocal ,
17+
| ^
18+
4 | nonlocal x,
19+
5 | nonlocal x, y,
20+
|
21+
22+
<filename>:4:15: SyntaxError: Trailing comma not allowed
23+
|
24+
2 | def f():
25+
3 | nonlocal ,
26+
4 | nonlocal x,
27+
| ^
28+
5 | nonlocal x, y,
29+
|
30+
31+
<filename>:5:18: SyntaxError: Trailing comma not allowed
32+
|
33+
3 | nonlocal ,
34+
4 | nonlocal x,
35+
5 | nonlocal x, y,
36+
| ^
37+
|
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
nonlocal x
2+
nonlocal x, y

crates/ruff_python_parser/resources/inline/err/nonlocal_stmt_empty.py

Lines changed: 0 additions & 1 deletion
This file was deleted.

crates/ruff_python_parser/resources/inline/err/nonlocal_stmt_expression.py

Lines changed: 0 additions & 1 deletion
This file was deleted.

crates/ruff_python_parser/resources/inline/err/nonlocal_stmt_trailing_comma.py

Lines changed: 0 additions & 3 deletions
This file was deleted.

0 commit comments

Comments
 (0)