WIP: use annotated parameters as type context

This commit is contained in:
Ibraheem Ahmed 2025-09-26 01:56:59 -04:00
parent e66a872c14
commit e33bf726d7
6 changed files with 271 additions and 40 deletions

View file

@ -1682,3 +1682,57 @@ def _(arg: tuple[A | B, Any]):
reveal_type(f(arg)) # revealed: Unknown
reveal_type(f(*(arg,))) # revealed: Unknown
```
## Bi-directional Type Inference
Type inference accounts for the type of each overload.
```py
from typing import TypedDict, overload
class T(TypedDict):
x: int
@overload
def f(a: list[T], b: int):
...
@overload
def f(a: list[dict[str, int]], b: str):
...
def f(a: list[dict[str, int]] | list[T], b: int | str):
...
def int_or_str() -> int | str:
return 1
f([{ "x": 1 }], int_or_str())
# error: [missing-typed-dict-key] "Missing required key 'x' in TypedDict `T` constructor"
# error: [invalid-key] "Invalid key access on TypedDict `T`: Unknown key "y""
f([{ "y": 1 }], int_or_str())
```
Non-matching overloads do not produce errors:
```py
from typing import TypedDict, overload
class T(TypedDict):
x: int
@overload
def f(a: T, b: int):
...
@overload
def f(a: dict[str, int], b: str):
...
def f(a: T | dict[str, int], b: int | str):
...
# TODO
f({ "y": 1 }, "a")
```

View file

@ -152,7 +152,7 @@ Person(name="Alice")
# error: [missing-typed-dict-key] "Missing required key 'age' in TypedDict `Person` constructor"
Person({"name": "Alice"})
# TODO: this should be an error, similar to the above
# error: [missing-typed-dict-key] "Missing required key 'age' in TypedDict `Person` constructor"
accepts_person({"name": "Alice"})
# TODO: this should be an error, similar to the above
house.owner = {"name": "Alice"}
@ -171,7 +171,7 @@ Person(name=None, age=30)
# error: [invalid-argument-type] "Invalid argument to key "name" with declared type `str` on TypedDict `Person`: value of type `None`"
Person({"name": None, "age": 30})
# TODO: this should be an error, similar to the above
# error: [invalid-argument-type] "Invalid argument to key "name" with declared type `str` on TypedDict `Person`: value of type `None`"
accepts_person({"name": None, "age": 30})
# TODO: this should be an error, similar to the above
house.owner = {"name": None, "age": 30}
@ -190,7 +190,7 @@ Person(name="Alice", age=30, extra=True)
# error: [invalid-key] "Invalid key access on TypedDict `Person`: Unknown key "extra""
Person({"name": "Alice", "age": 30, "extra": True})
# TODO: this should be an error
# error: [invalid-key] "Invalid key access on TypedDict `Person`: Unknown key "extra""
accepts_person({"name": "Alice", "age": 30, "extra": True})
# TODO: this should be an error
house.owner = {"name": "Alice", "age": 30, "extra": True}