Commit 5bf7742
authored
Fix missing type store for overloads (#16803)
Add missing call to store inferred types if an overload match is found
early. All other code paths already do that.
### Some background on the issue this fixes
I recently saw an interesting pattern in `aiohttp` to type values in an
`dict[str, Any]` by subclassing dict.
```py
T = TypeVar("T")
U = TypeVar("U")
class Key(Generic[T]):
...
class CustomDict(dict[Key[Any] | str, Any]):
@overload # type: ignore[override]
def get(self, __key: Key[T]) -> T | None:
...
@overload
def get(self, __key: Key[T], __default: U) -> T | U:
...
@overload
def get(self, __key: str) -> Any | None:
...
@overload
def get(self, __key: str, __default: Any) -> Any:
...
def get(self, __key: Key[Any] | str, __default: Any = None) -> Any:
"""Forward to super implementation."""
return super().get(__key, __default)
# overloads for __getitem__, setdefault, pop
# ...
@overload # type: ignore[override]
def __setitem__(self, key: Key[T], value: T) -> None:
...
@overload
def __setitem__(self, key: str, value: Any) -> None:
...
def __setitem__(self, key: Key[Any] | str, value: Any) -> None:
"""Forward to super implementation."""
return super().__setitem__(key, value)
```
With the exception that these overloads aren't technically compatible
with the supertype, they do the job.
```py
d = CustomDict()
key = Key[int]()
other_key = "other"
assert_type(d.get(key), int | None)
assert_type(d.get("other"), Any | None)
```
The issue exists for the `__setitem__` case. Without this PR the
following would create an issue. Here `var` would be inferred as
`dict[Never, Never]`, even though it should be `dict[Any, Any]` which is
the case for non-subclassed dicts.
```py
def a2(d: CustomDict) -> None:
if (var := d.get("arg")) is None:
var = d["arg"] = {}
reveal_type(var)
```1 parent 55247c4 commit 5bf7742
File tree
3 files changed
+46
-0
lines changed- mypy
- test-data/unit
3 files changed
+46
-0
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2825 | 2825 | | |
2826 | 2826 | | |
2827 | 2827 | | |
| 2828 | + | |
2828 | 2829 | | |
2829 | 2830 | | |
2830 | 2831 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1480 | 1480 | | |
1481 | 1481 | | |
1482 | 1482 | | |
| 1483 | + | |
| 1484 | + | |
| 1485 | + | |
| 1486 | + | |
| 1487 | + | |
| 1488 | + | |
| 1489 | + | |
| 1490 | + | |
| 1491 | + | |
| 1492 | + | |
| 1493 | + | |
| 1494 | + | |
| 1495 | + | |
| 1496 | + | |
| 1497 | + | |
| 1498 | + | |
| 1499 | + | |
| 1500 | + | |
| 1501 | + | |
| 1502 | + | |
| 1503 | + | |
| 1504 | + | |
| 1505 | + | |
| 1506 | + | |
1483 | 1507 | | |
1484 | 1508 | | |
1485 | 1509 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1236 | 1236 | | |
1237 | 1237 | | |
1238 | 1238 | | |
| 1239 | + | |
| 1240 | + | |
| 1241 | + | |
| 1242 | + | |
| 1243 | + | |
| 1244 | + | |
| 1245 | + | |
| 1246 | + | |
| 1247 | + | |
| 1248 | + | |
| 1249 | + | |
| 1250 | + | |
| 1251 | + | |
| 1252 | + | |
| 1253 | + | |
| 1254 | + | |
| 1255 | + | |
| 1256 | + | |
| 1257 | + | |
| 1258 | + | |
| 1259 | + | |
1239 | 1260 | | |
1240 | 1261 | | |
1241 | 1262 | | |
| |||
0 commit comments