diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 51a6f92e9ce6..c02200bd99e9 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -254,12 +254,12 @@ def check_typeddict_call_with_kwargs(self, callee: TypedDictType, for (item_name, item_expected_type) in callee.items.items(): item_value = kwargs[item_name] - item_actual_type = self.chk.check_simple_assignment( + self.chk.check_simple_assignment( lvalue_type=item_expected_type, rvalue=item_value, context=item_value, msg=messages.INCOMPATIBLE_TYPES, lvalue_name='TypedDict item "{}"'.format(item_name), rvalue_name='expression') - items[item_name] = item_actual_type + items[item_name] = item_expected_type mapping_value_type = join.join_type_list(list(items.values())) fallback = self.chk.named_generic_type('typing.Mapping', diff --git a/test-data/unit/check-typeddict.test b/test-data/unit/check-typeddict.test index 78fade8c8258..95bd83d50190 100644 --- a/test-data/unit/check-typeddict.test +++ b/test-data/unit/check-typeddict.test @@ -152,7 +152,7 @@ class Point(TypedDict): z = int # E: Invalid statement in TypedDict definition; expected "field_name: field_type" p = Point(x=42, y=1337, z='whatever') -reveal_type(p) # E: Revealed type is 'TypedDict(x=builtins.int, y=builtins.int, z=builtins.str, _fallback=typing.Mapping[builtins.str, builtins.object])' +reveal_type(p) # E: Revealed type is 'TypedDict(x=builtins.int, y=builtins.int, z=Any, _fallback=typing.Mapping[builtins.str, Any])' [builtins fixtures/dict.pyi] [case testCanCreateTypedDictTypeWithUnderscoreItemName] @@ -286,6 +286,44 @@ def as_mapping(p: Point) -> Mapping[str, str]: return p # E: Incompatible return value type (got "Point", expected Mapping[str, str]) [builtins fixtures/dict.pyi] +[case testTypedDictAcceptsIntForFloatDuckTypes] +from mypy_extensions import TypedDict +from typing import Any, Mapping +Point = TypedDict('Point', {'x': float, 'y': float}) +def create_point() -> Point: + return Point(x=1, y=2) +reveal_type(Point(x=1, y=2)) # E: Revealed type is 'TypedDict(x=builtins.float, y=builtins.float, _fallback=typing.Mapping[builtins.str, builtins.float])' +[builtins fixtures/dict.pyi] + +[case testTypedDictDoesNotAcceptsFloatForInt] +from mypy_extensions import TypedDict +from typing import Any, Mapping +Point = TypedDict('Point', {'x': int, 'y': int}) +def create_point() -> Point: + return Point(x=1.2, y=2.5) +[out] +main:5: error: Incompatible types (expression has type "float", TypedDict item "x" has type "int") +main:5: error: Incompatible types (expression has type "float", TypedDict item "y" has type "int") +[builtins fixtures/dict.pyi] + +[case testTypedDictAcceptsAnyType] +from mypy_extensions import TypedDict +from typing import Any, Mapping +Point = TypedDict('Point', {'x': float, 'y': float}) +def create_point(something: Any) -> Point: + return Point({ + 'x': something.x, + 'y': something.y + }) +[builtins fixtures/dict.pyi] + +[case testTypedDictValueTypeContext] +from mypy_extensions import TypedDict +from typing import List +D = TypedDict('D', {'x': List[int]}) +reveal_type(D(x=[])) # E: Revealed type is 'TypedDict(x=builtins.list[builtins.int], _fallback=typing.Mapping[builtins.str, builtins.list[builtins.int]])' +[builtins fixtures/dict.pyi] + -- TODO: Fix mypy stubs so that the following passes in the test suite --[case testCanConvertTypedDictToAnySuperclassOfMapping] --from mypy_extensions import TypedDict @@ -341,9 +379,9 @@ CellWithObject = TypedDict('CellWithObject', {'value': object, 'meta': object}) c1 = CellWithInt(value=1, meta=42) c2 = CellWithObject(value=2, meta='turtle doves') joined_cells = [c1, c2] -reveal_type(c1) # E: Revealed type is 'TypedDict(value=builtins.int, meta=builtins.int, _fallback=typing.Mapping[builtins.str, builtins.int])' -reveal_type(c2) # E: Revealed type is 'TypedDict(value=builtins.int, meta=builtins.str, _fallback=typing.Mapping[builtins.str, builtins.object])' -reveal_type(joined_cells) # E: Revealed type is 'builtins.list[TypedDict(value=builtins.int, _fallback=typing.Mapping[builtins.str, builtins.int])]' +reveal_type(c1) # E: Revealed type is 'TypedDict(value=builtins.object, meta=builtins.int, _fallback=typing.Mapping[builtins.str, builtins.object])' +reveal_type(c2) # E: Revealed type is 'TypedDict(value=builtins.object, meta=builtins.object, _fallback=typing.Mapping[builtins.str, builtins.object])' +reveal_type(joined_cells) # E: Revealed type is 'builtins.list[TypedDict(value=builtins.object, _fallback=typing.Mapping[builtins.str, builtins.object])]' [builtins fixtures/dict.pyi] [case testJoinOfDisjointTypedDictsIsEmptyTypedDict] @@ -354,7 +392,7 @@ d1 = Point(x=0, y=0) d2 = Cell(value='pear tree') joined_dicts = [d1, d2] reveal_type(d1) # E: Revealed type is 'TypedDict(x=builtins.int, y=builtins.int, _fallback=typing.Mapping[builtins.str, builtins.int])' -reveal_type(d2) # E: Revealed type is 'TypedDict(value=builtins.str, _fallback=typing.Mapping[builtins.str, builtins.str])' +reveal_type(d2) # E: Revealed type is 'TypedDict(value=builtins.object, _fallback=typing.Mapping[builtins.str, builtins.object])' reveal_type(joined_dicts) # E: Revealed type is 'builtins.list[TypedDict(_fallback=typing.Mapping[builtins.str, ])]' [builtins fixtures/dict.pyi]