Skip to content

Commit 8de5a3d

Browse files
Allow Final assignments in stubs (#5490)
## Summary This fixes one incompatibility with `flake8-pyi`, and gives us a clean pass on `typeshed`.
1 parent ed1dd09 commit 8de5a3d

File tree

3 files changed

+15
-0
lines changed

3 files changed

+15
-0
lines changed

crates/ruff/resources/test/fixtures/flake8_pyi/PYI015.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,4 @@ class Class1:
9191
field28 = builtins.str
9292
field29 = str
9393
field30 = str | bytes | None
94+
field31: typing.Final = field30

crates/ruff/resources/test/fixtures/flake8_pyi/PYI015.pyi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,4 @@ field27 = list[str]
9898
field28 = builtins.str
9999
field29 = str
100100
field30 = str | bytes | None
101+
field31: typing.Final = field30

crates/ruff/src/rules/flake8_pyi/rules/simple_defaults.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,16 @@ fn is_special_assignment(target: &Expr, semantic: &SemanticModel) -> bool {
298298
}
299299
}
300300

301+
/// Returns `true` if this is an assignment to a simple `Final`-annotated variable.
302+
fn is_final_assignment(annotation: &Expr, value: &Expr, semantic: &SemanticModel) -> bool {
303+
if matches!(value, Expr::Name(_) | Expr::Attribute(_)) {
304+
if semantic.match_typing_expr(annotation, "Final") {
305+
return true;
306+
}
307+
}
308+
false
309+
}
310+
301311
/// Returns `true` if the a class is an enum, based on its base classes.
302312
fn is_enum(bases: &[Expr], semantic: &SemanticModel) -> bool {
303313
return bases.iter().any(|expr| {
@@ -438,6 +448,9 @@ pub(crate) fn annotated_assignment_default_in_stub(
438448
if is_type_var_like_call(value, checker.semantic()) {
439449
return;
440450
}
451+
if is_final_assignment(annotation, value, checker.semantic()) {
452+
return;
453+
}
441454
if is_valid_default_value_with_annotation(value, true, checker.locator, checker.semantic()) {
442455
return;
443456
}

0 commit comments

Comments
 (0)