[red-knot] Infer attribute expressions in type annotations (#13967)

This commit is contained in:
Alex Waygood 2024-10-29 11:06:44 +00:00 committed by GitHub
parent d2c9f5e43c
commit 8d98aea6c4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 24 additions and 11 deletions

View file

@ -91,3 +91,20 @@ def baz() -> str | str:
reveal_type(baz()) # revealed: str reveal_type(baz()) # revealed: str
``` ```
## Attribute expressions in type annotations are understood
```py
import builtins
int = "foo"
a: builtins.int = 42
# error: [invalid-assignment] "Object of type `Literal["bar"]` is not assignable to `int`"
b: builtins.int = "bar"
c: builtins.tuple[builtins.tuple[builtins.int, builtins.int], builtins.int] = ((42, 42), 42)
# error: [invalid-assignment] "Object of type `Literal["foo"]` is not assignable to `tuple[tuple[int, int], int]`"
c: builtins.tuple[builtins.tuple[builtins.int, builtins.int], builtins.int] = "foo"
```

View file

@ -3542,15 +3542,16 @@ impl<'db> TypeInferenceBuilder<'db> {
let ty = match expression { let ty = match expression {
ast::Expr::Name(name) => { ast::Expr::Name(name) => {
debug_assert!( debug_assert_eq!(name.ctx, ast::ExprContext::Load);
name.ctx.is_load(),
"name in a type expression is always 'load' but got: '{:?}'",
name.ctx
);
self.infer_name_expression(name).to_instance(self.db) self.infer_name_expression(name).to_instance(self.db)
} }
ast::Expr::Attribute(attribute_expression) => {
debug_assert_eq!(attribute_expression.ctx, ast::ExprContext::Load);
self.infer_attribute_expression(attribute_expression)
.to_instance(self.db)
}
ast::Expr::NoneLiteral(_literal) => Type::None, ast::Expr::NoneLiteral(_literal) => Type::None,
// TODO: parse the expression and check whether it is a string annotation. // TODO: parse the expression and check whether it is a string annotation.
@ -3684,11 +3685,6 @@ impl<'db> TypeInferenceBuilder<'db> {
self.infer_fstring_expression(fstring); self.infer_fstring_expression(fstring);
Type::Unknown Type::Unknown
} }
//
ast::Expr::Attribute(attribute) => {
self.infer_attribute_expression(attribute);
Type::Unknown
}
ast::Expr::List(list) => { ast::Expr::List(list) => {
self.infer_list_expression(list); self.infer_list_expression(list);
Type::Unknown Type::Unknown