mirror of https://github.com/astral-sh/ruff
support dictionary literal `TypedDict` constructors
This commit is contained in:
parent
b753851379
commit
2949f76b47
|
|
@ -315,6 +315,8 @@ Person(name="Alice", age=30, extra=True) # type: ignore
|
|||
The positional dictionary constructor pattern (used by libraries like strawberry) should work
|
||||
correctly:
|
||||
|
||||
`class.py`:
|
||||
|
||||
```py
|
||||
from typing import TypedDict
|
||||
|
||||
|
|
@ -335,6 +337,26 @@ user3 = User({"name": None, "age": 25})
|
|||
user4 = User({"name": "Charlie", "age": 30, "extra": True})
|
||||
```
|
||||
|
||||
`functional.py`:
|
||||
|
||||
```py
|
||||
from typing import TypedDict
|
||||
|
||||
User = TypedDict("User", {"name": str, "age": int})
|
||||
|
||||
# Valid usage - all required fields provided
|
||||
user1 = User({"name": "Alice", "age": 30})
|
||||
|
||||
# error: [missing-typed-dict-key] "Missing required key 'age' in TypedDict `User` constructor"
|
||||
user2 = User({"name": "Bob"})
|
||||
|
||||
# error: [invalid-argument-type] "Invalid argument to key "name" with declared type `str` on TypedDict `User`: value of type `None`"
|
||||
user3 = User({"name": None, "age": 25})
|
||||
|
||||
# error: [invalid-key] "Invalid key access on TypedDict `User`: Unknown key "extra""
|
||||
user4 = User({"name": "Charlie", "age": 30, "extra": True})
|
||||
```
|
||||
|
||||
## Optional fields with `total=False`
|
||||
|
||||
By default, all fields in a `TypedDict` are required (`total=True`). You can make all fields
|
||||
|
|
|
|||
|
|
@ -4865,16 +4865,21 @@ impl<'db> Type<'db> {
|
|||
|
||||
Type::EnumLiteral(enum_literal) => enum_literal.enum_class_instance(db).bindings(db),
|
||||
|
||||
Type::KnownInstance(KnownInstanceType::TypedDictType(typed_dict)) => Binding::single(
|
||||
self,
|
||||
Signature::new(
|
||||
// TODO: List more specific parameter types here for better code completion.
|
||||
Parameters::new([Parameter::keyword_variadic(Name::new_static("kwargs"))
|
||||
.with_annotated_type(Type::any())]),
|
||||
Some(Type::TypedDict(TypedDictType::Synthesized(typed_dict))),
|
||||
),
|
||||
)
|
||||
.into(),
|
||||
Type::KnownInstance(KnownInstanceType::TypedDictType(typed_dict)) => {
|
||||
CallableBinding::from_overloads(
|
||||
self,
|
||||
[Signature::new(
|
||||
// TODO: List more specific parameter types here for better code completion.
|
||||
Parameters::new([
|
||||
Parameter::variadic(Name::new_static("args")),
|
||||
Parameter::keyword_variadic(Name::new_static("kwargs"))
|
||||
.with_annotated_type(Type::any()),
|
||||
]),
|
||||
Some(Type::TypedDict(TypedDictType::Synthesized(typed_dict))),
|
||||
)],
|
||||
)
|
||||
.into()
|
||||
}
|
||||
|
||||
Type::KnownInstance(known_instance) => {
|
||||
known_instance.instance_fallback(db).bindings(db)
|
||||
|
|
|
|||
Loading…
Reference in New Issue