diff --git a/mypy/constraints.py b/mypy/constraints.py index d65a418df37b..264d03e10c0c 100644 --- a/mypy/constraints.py +++ b/mypy/constraints.py @@ -312,6 +312,8 @@ def visit_instance(self, template: Instance) -> List[Constraint]: res = [] # type: List[Constraint] if isinstance(actual, CallableType) and actual.fallback is not None: actual = actual.fallback + if isinstance(actual, TypedDictType): + actual = actual.as_anonymous().fallback if isinstance(actual, Instance): instance = actual if (self.direction == SUBTYPE_OF and diff --git a/test-data/unit/check-typeddict.test b/test-data/unit/check-typeddict.test index d50cf27344cc..72b64a8af098 100644 --- a/test-data/unit/check-typeddict.test +++ b/test-data/unit/check-typeddict.test @@ -557,6 +557,17 @@ reveal_type(f(g)) # E: Revealed type is '' -- Constraint Solver +[case testTypedDictConstraintsAgainstIterable] +from typing import TypeVar, Iterable +from mypy_extensions import TypedDict +T = TypeVar('T') +def f(x: Iterable[T]) -> T: pass +A = TypedDict('A', {'x': int}) +a: A +reveal_type(f(a)) # E: Revealed type is 'builtins.str*' +[builtins fixtures/dict.pyi] +[typing fixtures/typing-full.pyi] + -- TODO: Figure out some way to trigger the ConstraintBuilderVisitor.visit_typeddict_type() path. diff --git a/test-data/unit/fixtures/dict.pyi b/test-data/unit/fixtures/dict.pyi index e920512274dd..62234c69d0b2 100644 --- a/test-data/unit/fixtures/dict.pyi +++ b/test-data/unit/fixtures/dict.pyi @@ -11,7 +11,7 @@ class object: class type: pass -class dict(Iterable[KT], Mapping[KT, VT], Generic[KT, VT]): +class dict(Mapping[KT, VT], Iterable[KT], Generic[KT, VT]): @overload def __init__(self, **kwargs: VT) -> None: pass @overload diff --git a/test-data/unit/fixtures/typing-full.pyi b/test-data/unit/fixtures/typing-full.pyi index 463b117db48d..cb632b3de304 100644 --- a/test-data/unit/fixtures/typing-full.pyi +++ b/test-data/unit/fixtures/typing-full.pyi @@ -103,12 +103,12 @@ class Sequence(Iterable[T], Generic[T]): @abstractmethod def __getitem__(self, n: Any) -> T: pass -class Mapping(Generic[T, U]): +class Mapping(Iterable[T], Generic[T, U]): @overload def get(self, k: T) -> Optional[U]: ... @overload def get(self, k: T, default: Union[U, V]) -> Union[U, V]: ... -class MutableMapping(Generic[T, U]): pass +class MutableMapping(Mapping[T, U]): pass TYPE_CHECKING = 1