Allow Final assignments in stubs (#5490)

## Summary

This fixes one incompatibility with `flake8-pyi`, and gives us a clean
pass on `typeshed`.
This commit is contained in:
Charlie Marsh 2023-07-03 13:57:49 -04:00 committed by GitHub
parent ed1dd09d02
commit 8de5a3d29d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 15 additions and 0 deletions

View file

@ -91,3 +91,4 @@ field27 = list[str]
field28 = builtins.str field28 = builtins.str
field29 = str field29 = str
field30 = str | bytes | None field30 = str | bytes | None
field31: typing.Final = field30

View file

@ -98,3 +98,4 @@ field27 = list[str]
field28 = builtins.str field28 = builtins.str
field29 = str field29 = str
field30 = str | bytes | None field30 = str | bytes | None
field31: typing.Final = field30

View file

@ -298,6 +298,16 @@ fn is_special_assignment(target: &Expr, semantic: &SemanticModel) -> bool {
} }
} }
/// Returns `true` if this is an assignment to a simple `Final`-annotated variable.
fn is_final_assignment(annotation: &Expr, value: &Expr, semantic: &SemanticModel) -> bool {
if matches!(value, Expr::Name(_) | Expr::Attribute(_)) {
if semantic.match_typing_expr(annotation, "Final") {
return true;
}
}
false
}
/// Returns `true` if the a class is an enum, based on its base classes. /// Returns `true` if the a class is an enum, based on its base classes.
fn is_enum(bases: &[Expr], semantic: &SemanticModel) -> bool { fn is_enum(bases: &[Expr], semantic: &SemanticModel) -> bool {
return bases.iter().any(|expr| { return bases.iter().any(|expr| {
@ -438,6 +448,9 @@ pub(crate) fn annotated_assignment_default_in_stub(
if is_type_var_like_call(value, checker.semantic()) { if is_type_var_like_call(value, checker.semantic()) {
return; return;
} }
if is_final_assignment(annotation, value, checker.semantic()) {
return;
}
if is_valid_default_value_with_annotation(value, true, checker.locator, checker.semantic()) { if is_valid_default_value_with_annotation(value, true, checker.locator, checker.semantic()) {
return; return;
} }