Closed
Description
Bug Report
(A clear and concise description of what the bug is.)
To Reproduce
from typing import Any, Dict, List, TypedDict, TypeVar, Type, TYPE_CHECKING
class User(TypedDict):
id: int
name: str
users: List[Dict[str, Any]] = [{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}]
T = TypeVar("T")
def try_cast(cls: Type[T], data: Any) -> T:
return cls(**data) # type: ignore
for user in users:
user_unannotated = try_cast(User, user)
user_annotated: User = try_cast(User, user) # Incompatible types in assignment (expression has type "User", variable has type "User")
if TYPE_CHECKING:
reveal_type(try_cast) # def [T] (cls: Type[T`-1], data: Any) -> T`-1
reveal_type(try_cast(User, {})) # typed.User*
reveal_type(user) # builtins.dict*[builtins.str, Any]
reveal_type(user_unannotated) # typed.User*
reveal_type(user_unannotated["id"]) # builtins.object*
reveal_type(user_annotated) # TypedDict('typed.User', {'id': builtins.int, 'name': builtins.str})
reveal_type(user_annotated["id"]) # builtins.int
Run mypy one the above code. It will generate an error like Incompatible types in assignment (expression has type "User", variable has type "User")
Expected Behavior
Mypy should accept both variants of the try_cast
call and the type of user_...["id"]
should be int
in both cases.
Actual Behavior
The first invocation of try_cast
works but the id
attribute has the wrong type.
The second invocation of try_cast
has an error however the id
attribute has the correct type.
Your Environment
- Mypy version used:
mypy 0.812
- Mypy command-line flags: -
- Mypy configuration options from
mypy.ini
(and other config files): - - Python version used:
Python 3.8.6
- Operating system and version:
Ubuntu 20.10
Additional Details
Pyright shows the expected behaviour here:
/tmp/septatrix-playground-2021-06-08T14-58-03-QGJ/typed.py:19:21 - info: Type of "try_cast" is "(cls: Type[T@try_cast], data: Any) -> T@try_cast"
/tmp/septatrix-playground-2021-06-08T14-58-03-QGJ/typed.py:20:21 - info: Type of "try_cast(User, { })" is "User"
/tmp/septatrix-playground-2021-06-08T14-58-03-QGJ/typed.py:21:21 - info: Type of "user" is "Dict[str, Any]"
/tmp/septatrix-playground-2021-06-08T14-58-03-QGJ/typed.py:22:21 - info: Type of "user_unannotated" is "User"
/tmp/septatrix-playground-2021-06-08T14-58-03-QGJ/typed.py:23:21 - info: Type of "user_unannotated["id"]" is "int"
/tmp/septatrix-playground-2021-06-08T14-58-03-QGJ/typed.py:24:21 - info: Type of "user_annotated" is "User"
/tmp/septatrix-playground-2021-06-08T14-58-03-QGJ/typed.py:25:21 - info: Type of "user_annotated["id"]" is "int"