mirror of https://github.com/astral-sh/ruff
Merge bce4e2ca2b into b0bc990cbf
This commit is contained in:
commit
e3a034b8e1
30
crates/ruff_linter/resources/test/fixtures/semantic_errors/annotated_global.py
vendored
Normal file
30
crates/ruff_linter/resources/test/fixtures/semantic_errors/annotated_global.py
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
a: int = 1
|
||||||
|
def f1():
|
||||||
|
global a
|
||||||
|
a: str = "foo" # error
|
||||||
|
|
||||||
|
b: int = 1
|
||||||
|
def outer():
|
||||||
|
def inner():
|
||||||
|
global b
|
||||||
|
b: str = "nested" # error
|
||||||
|
|
||||||
|
c: int = 1
|
||||||
|
def f2():
|
||||||
|
global c
|
||||||
|
c: list[str] = [] # error
|
||||||
|
|
||||||
|
d: int = 1
|
||||||
|
def f3():
|
||||||
|
global d
|
||||||
|
d: str # error
|
||||||
|
|
||||||
|
e: int = 1
|
||||||
|
def f4():
|
||||||
|
e: str = "happy" # okay
|
||||||
|
|
||||||
|
global f
|
||||||
|
f: int = 1 # okay
|
||||||
|
|
||||||
|
g: int = 1
|
||||||
|
global g # error
|
||||||
|
|
@ -1001,6 +1001,7 @@ mod tests {
|
||||||
#[test_case(Path::new("write_to_debug.py"), PythonVersion::PY310)]
|
#[test_case(Path::new("write_to_debug.py"), PythonVersion::PY310)]
|
||||||
#[test_case(Path::new("invalid_expression.py"), PythonVersion::PY312)]
|
#[test_case(Path::new("invalid_expression.py"), PythonVersion::PY312)]
|
||||||
#[test_case(Path::new("global_parameter.py"), PythonVersion::PY310)]
|
#[test_case(Path::new("global_parameter.py"), PythonVersion::PY310)]
|
||||||
|
#[test_case(Path::new("annotated_global.py"), PythonVersion::PY314)]
|
||||||
fn test_semantic_errors(path: &Path, python_version: PythonVersion) -> Result<()> {
|
fn test_semantic_errors(path: &Path, python_version: PythonVersion) -> Result<()> {
|
||||||
let snapshot = format!(
|
let snapshot = format!(
|
||||||
"semantic_syntax_error_{}_{}",
|
"semantic_syntax_error_{}_{}",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_linter/src/linter.rs
|
||||||
|
---
|
||||||
|
invalid-syntax: annotated name `a` can't be global
|
||||||
|
--> resources/test/fixtures/semantic_errors/annotated_global.py:4:5
|
||||||
|
|
|
||||||
|
2 | def f1():
|
||||||
|
3 | global a
|
||||||
|
4 | a: str = "foo" # error
|
||||||
|
| ^
|
||||||
|
5 |
|
||||||
|
6 | b: int = 1
|
||||||
|
|
|
||||||
|
|
||||||
|
invalid-syntax: annotated name `b` can't be global
|
||||||
|
--> resources/test/fixtures/semantic_errors/annotated_global.py:10:9
|
||||||
|
|
|
||||||
|
8 | def inner():
|
||||||
|
9 | global b
|
||||||
|
10 | b: str = "nested" # error
|
||||||
|
| ^
|
||||||
|
11 |
|
||||||
|
12 | c: int = 1
|
||||||
|
|
|
||||||
|
|
||||||
|
invalid-syntax: annotated name `c` can't be global
|
||||||
|
--> resources/test/fixtures/semantic_errors/annotated_global.py:15:5
|
||||||
|
|
|
||||||
|
13 | def f2():
|
||||||
|
14 | global c
|
||||||
|
15 | c: list[str] = [] # error
|
||||||
|
| ^
|
||||||
|
16 |
|
||||||
|
17 | d: int = 1
|
||||||
|
|
|
||||||
|
|
||||||
|
invalid-syntax: annotated name `d` can't be global
|
||||||
|
--> resources/test/fixtures/semantic_errors/annotated_global.py:20:5
|
||||||
|
|
|
||||||
|
18 | def f3():
|
||||||
|
19 | global d
|
||||||
|
20 | d: str # error
|
||||||
|
| ^
|
||||||
|
21 |
|
||||||
|
22 | e: int = 1
|
||||||
|
|
|
||||||
|
|
||||||
|
invalid-syntax: annotated name `g` can't be global
|
||||||
|
--> resources/test/fixtures/semantic_errors/annotated_global.py:29:1
|
||||||
|
|
|
||||||
|
27 | f: int = 1 # okay
|
||||||
|
28 |
|
||||||
|
29 | g: int = 1
|
||||||
|
| ^
|
||||||
|
30 | global g # error
|
||||||
|
|
|
||||||
|
|
@ -272,7 +272,9 @@ impl SemanticSyntaxChecker {
|
||||||
|
|
||||||
fn check_annotation<Ctx: SemanticSyntaxContext>(stmt: &ast::Stmt, ctx: &Ctx) {
|
fn check_annotation<Ctx: SemanticSyntaxContext>(stmt: &ast::Stmt, ctx: &Ctx) {
|
||||||
match stmt {
|
match stmt {
|
||||||
Stmt::AnnAssign(ast::StmtAnnAssign { annotation, .. }) => {
|
Stmt::AnnAssign(ast::StmtAnnAssign {
|
||||||
|
target, annotation, ..
|
||||||
|
}) => {
|
||||||
if ctx.python_version() > PythonVersion::PY313 {
|
if ctx.python_version() > PythonVersion::PY313 {
|
||||||
// test_ok valid_annotation_py313
|
// test_ok valid_annotation_py313
|
||||||
// # parse_options: {"target-version": "3.13"}
|
// # parse_options: {"target-version": "3.13"}
|
||||||
|
|
@ -297,6 +299,18 @@ impl SemanticSyntaxChecker {
|
||||||
};
|
};
|
||||||
visitor.visit_expr(annotation);
|
visitor.visit_expr(annotation);
|
||||||
}
|
}
|
||||||
|
if let Expr::Name(ast::ExprName { id, .. }) = target.as_ref() {
|
||||||
|
if let Some(global_stmt) = ctx.global(id.as_str()) {
|
||||||
|
let global_start = global_stmt.start();
|
||||||
|
if ctx.in_function_scope() || target.start() < global_start {
|
||||||
|
Self::add_error(
|
||||||
|
ctx,
|
||||||
|
SemanticSyntaxErrorKind::AnnotatedGlobal(id.to_string()),
|
||||||
|
target.range(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Stmt::FunctionDef(ast::StmtFunctionDef {
|
Stmt::FunctionDef(ast::StmtFunctionDef {
|
||||||
type_params,
|
type_params,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue