diff --git a/mypy/checker.py b/mypy/checker.py index 5cbb884d2898..c65f9563afdd 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -2339,7 +2339,9 @@ def named_type(self, name: str) -> Instance: """ # Assume that the name refers to a type. sym = self.lookup_qualified(name) - return Instance(cast(TypeInfo, sym.node), []) + node = sym.node + assert isinstance(node, TypeInfo) + return Instance(node, [AnyType()] * len(node.defn.type_vars)) def named_generic_type(self, name: str, args: List[Type]) -> Instance: """Return an instance with the given name and type arguments. @@ -2347,12 +2349,16 @@ def named_generic_type(self, name: str, args: List[Type]) -> Instance: Assume that the number of arguments is correct. Assume that the name refers to a compatible generic type. """ - return Instance(self.lookup_typeinfo(name), args) + info = self.lookup_typeinfo(name) + # TODO: assert len(args) == len(info.defn.type_vars) + return Instance(info, args) def lookup_typeinfo(self, fullname: str) -> TypeInfo: # Assume that the name refers to a class. sym = self.lookup_qualified(fullname) - return cast(TypeInfo, sym.node) + node = sym.node + assert isinstance(node, TypeInfo) + return node def type_type(self) -> Instance: """Return instance type 'type'.""" diff --git a/mypy/semanal.py b/mypy/semanal.py index a5beb418e538..729ed84bcc19 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -1063,15 +1063,23 @@ def class_type(self, info: TypeInfo) -> Type: def named_type(self, qualified_name: str, args: List[Type] = None) -> Instance: sym = self.lookup_qualified(qualified_name, None) - assert isinstance(sym.node, TypeInfo) - return Instance(sym.node, args or []) + node = sym.node + assert isinstance(node, TypeInfo) + if args: + # TODO: assert len(args) == len(node.defn.type_vars) + return Instance(node, args) + return Instance(node, [AnyType()] * len(node.defn.type_vars)) def named_type_or_none(self, qualified_name: str, args: List[Type] = None) -> Instance: sym = self.lookup_fully_qualified_or_none(qualified_name) if not sym: return None - assert isinstance(sym.node, TypeInfo) - return Instance(sym.node, args or []) + node = sym.node + assert isinstance(node, TypeInfo) + if args: + # TODO: assert len(args) == len(node.defn.type_vars) + return Instance(node, args) + return Instance(node, [AnyType()] * len(node.defn.type_vars)) def is_typeddict(self, expr: Expression) -> bool: return (isinstance(expr, RefExpr) and isinstance(expr.node, TypeInfo) and @@ -2040,7 +2048,9 @@ def build_namedtuple_typeinfo(self, name: str, items: List[str], types: List[Typ # Actual signature should return OrderedDict[str, Union[types]] ordereddictype = (self.named_type_or_none('builtins.dict', [strtype, AnyType()]) or self.object_type()) - fallback = self.named_type('__builtins__.tuple', types) + # 'builtins.tuple' has only one type parameter, the corresponding type argument + # in the fallback instance is a join of all item types. + fallback = self.named_type('__builtins__.tuple', [join.join_type_list(types)]) # Note: actual signature should accept an invariant version of Iterable[UnionType[types]]. # but it can't be expressed. 'new' and 'len' should be callable types. iterable_type = self.named_type_or_none('typing.Iterable', [AnyType()]) @@ -3113,9 +3123,10 @@ def lookup_qualified(self, name: str, ctx: Context) -> SymbolTableNode: return n def builtin_type(self, fully_qualified_name: str) -> Instance: - node = self.lookup_fully_qualified(fully_qualified_name) - assert isinstance(node.node, TypeInfo) - return Instance(node.node, []) + sym = self.lookup_fully_qualified(fully_qualified_name) + node = sym.node + assert isinstance(node, TypeInfo) + return Instance(node, [AnyType()] * len(node.defn.type_vars)) def lookup_fully_qualified(self, name: str) -> SymbolTableNode: """Lookup a fully qualified name. @@ -3673,8 +3684,12 @@ def fail_blocker(self, msg: str, ctx: Context) -> None: def builtin_type(self, name: str, args: List[Type] = None) -> Instance: names = self.modules['builtins'] sym = names.names[name] - assert isinstance(sym.node, TypeInfo) - return Instance(sym.node, args or []) + node = sym.node + assert isinstance(node, TypeInfo) + if args: + # TODO: assert len(args) == len(node.defn.type_vars) + return Instance(node, args) + return Instance(node, [AnyType()] * len(node.defn.type_vars)) def replace_implicit_first_type(sig: FunctionLike, new: Type) -> FunctionLike: diff --git a/test-data/unit/check-async-await.test b/test-data/unit/check-async-await.test index 3c2f4c6b84ba..672bf2b408b8 100644 --- a/test-data/unit/check-async-await.test +++ b/test-data/unit/check-async-await.test @@ -84,7 +84,7 @@ async def f() -> int: x = await g() return x [out] -main:7: error: Incompatible types in await (actual type Generator[int, None, str], expected type "Awaitable") +main:7: error: Incompatible types in await (actual type Generator[int, None, str], expected type Awaitable[Any]) [case testAwaitIteratorError] @@ -95,7 +95,7 @@ async def f() -> int: x = await g() return x [out] -main:6: error: Incompatible types in await (actual type Iterator[Any], expected type "Awaitable") +main:6: error: Incompatible types in await (actual type Iterator[Any], expected type Awaitable[Any]) [case testAwaitArgumentError] @@ -106,7 +106,7 @@ async def f() -> int: return x [builtins fixtures/async_await.pyi] [out] -main:5: error: Incompatible types in await (actual type "int", expected type "Awaitable") +main:5: error: Incompatible types in await (actual type "int", expected type Awaitable[Any]) [case testAwaitResultError] @@ -271,7 +271,7 @@ class C: def __aenter__(self) -> int: pass async def __aexit__(self, x, y, z) -> None: pass async def f() -> None: - async with C() as x: # E: Incompatible types in "async with" for __aenter__ (actual type "int", expected type "Awaitable") + async with C() as x: # E: Incompatible types in "async with" for __aenter__ (actual type "int", expected type Awaitable[Any]) pass [builtins fixtures/async_await.pyi] [out] @@ -293,7 +293,7 @@ class C: async def __aenter__(self) -> int: pass def __aexit__(self, x, y, z) -> int: pass async def f() -> None: - async with C() as x: # E: Incompatible types in "async with" for __aexit__ (actual type "int", expected type "Awaitable") + async with C() as x: # E: Incompatible types in "async with" for __aexit__ (actual type "int", expected type Awaitable[Any]) pass [builtins fixtures/async_await.pyi] [out] @@ -615,11 +615,11 @@ def plain_host_generator() -> Generator[str, None, None]: async def plain_host_coroutine() -> None: x = 0 - x = await plain_generator() # E: Incompatible types in await (actual type Generator[str, None, int], expected type "Awaitable") + x = await plain_generator() # E: Incompatible types in await (actual type Generator[str, None, int], expected type Awaitable[Any]) x = await plain_coroutine() x = await decorated_generator() x = await decorated_coroutine() - x = await other_iterator() # E: Incompatible types in await (actual type "It", expected type "Awaitable") + x = await other_iterator() # E: Incompatible types in await (actual type "It", expected type Awaitable[Any]) x = await other_coroutine() @coroutine @@ -636,11 +636,11 @@ def decorated_host_generator() -> Generator[str, None, None]: @coroutine async def decorated_host_coroutine() -> None: x = 0 - x = await plain_generator() # E: Incompatible types in await (actual type Generator[str, None, int], expected type "Awaitable") + x = await plain_generator() # E: Incompatible types in await (actual type Generator[str, None, int], expected type Awaitable[Any]) x = await plain_coroutine() x = await decorated_generator() x = await decorated_coroutine() - x = await other_iterator() # E: Incompatible types in await (actual type "It", expected type "Awaitable") + x = await other_iterator() # E: Incompatible types in await (actual type "It", expected type Awaitable[Any]) x = await other_coroutine() [builtins fixtures/async_await.pyi] diff --git a/test-data/unit/fixtures/list.pyi b/test-data/unit/fixtures/list.pyi index 4d811813776d..0547a55d8942 100644 --- a/test-data/unit/fixtures/list.pyi +++ b/test-data/unit/fixtures/list.pyi @@ -23,7 +23,7 @@ class list(Iterable[T], Generic[T]): def append(self, x: T) -> None: pass def extend(self, x: Iterable[T]) -> None: pass -class tuple: pass +class tuple(Generic[T]): pass class function: pass class int: pass class float: pass