Skip to content

Commit d423061

Browse files
authored
Always create correct instances (#3305)
* Avoid creating wrong instances * Fix test * Add clarifying comment
1 parent 27a8437 commit d423061

File tree

4 files changed

+44
-23
lines changed

4 files changed

+44
-23
lines changed

mypy/checker.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2339,20 +2339,26 @@ def named_type(self, name: str) -> Instance:
23392339
"""
23402340
# Assume that the name refers to a type.
23412341
sym = self.lookup_qualified(name)
2342-
return Instance(cast(TypeInfo, sym.node), [])
2342+
node = sym.node
2343+
assert isinstance(node, TypeInfo)
2344+
return Instance(node, [AnyType()] * len(node.defn.type_vars))
23432345

23442346
def named_generic_type(self, name: str, args: List[Type]) -> Instance:
23452347
"""Return an instance with the given name and type arguments.
23462348
23472349
Assume that the number of arguments is correct. Assume that
23482350
the name refers to a compatible generic type.
23492351
"""
2350-
return Instance(self.lookup_typeinfo(name), args)
2352+
info = self.lookup_typeinfo(name)
2353+
# TODO: assert len(args) == len(info.defn.type_vars)
2354+
return Instance(info, args)
23512355

23522356
def lookup_typeinfo(self, fullname: str) -> TypeInfo:
23532357
# Assume that the name refers to a class.
23542358
sym = self.lookup_qualified(fullname)
2355-
return cast(TypeInfo, sym.node)
2359+
node = sym.node
2360+
assert isinstance(node, TypeInfo)
2361+
return node
23562362

23572363
def type_type(self) -> Instance:
23582364
"""Return instance type 'type'."""

mypy/semanal.py

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,15 +1063,23 @@ def class_type(self, info: TypeInfo) -> Type:
10631063

10641064
def named_type(self, qualified_name: str, args: List[Type] = None) -> Instance:
10651065
sym = self.lookup_qualified(qualified_name, None)
1066-
assert isinstance(sym.node, TypeInfo)
1067-
return Instance(sym.node, args or [])
1066+
node = sym.node
1067+
assert isinstance(node, TypeInfo)
1068+
if args:
1069+
# TODO: assert len(args) == len(node.defn.type_vars)
1070+
return Instance(node, args)
1071+
return Instance(node, [AnyType()] * len(node.defn.type_vars))
10681072

10691073
def named_type_or_none(self, qualified_name: str, args: List[Type] = None) -> Instance:
10701074
sym = self.lookup_fully_qualified_or_none(qualified_name)
10711075
if not sym:
10721076
return None
1073-
assert isinstance(sym.node, TypeInfo)
1074-
return Instance(sym.node, args or [])
1077+
node = sym.node
1078+
assert isinstance(node, TypeInfo)
1079+
if args:
1080+
# TODO: assert len(args) == len(node.defn.type_vars)
1081+
return Instance(node, args)
1082+
return Instance(node, [AnyType()] * len(node.defn.type_vars))
10751083

10761084
def is_typeddict(self, expr: Expression) -> bool:
10771085
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
20402048
# Actual signature should return OrderedDict[str, Union[types]]
20412049
ordereddictype = (self.named_type_or_none('builtins.dict', [strtype, AnyType()])
20422050
or self.object_type())
2043-
fallback = self.named_type('__builtins__.tuple', types)
2051+
# 'builtins.tuple' has only one type parameter, the corresponding type argument
2052+
# in the fallback instance is a join of all item types.
2053+
fallback = self.named_type('__builtins__.tuple', [join.join_type_list(types)])
20442054
# Note: actual signature should accept an invariant version of Iterable[UnionType[types]].
20452055
# but it can't be expressed. 'new' and 'len' should be callable types.
20462056
iterable_type = self.named_type_or_none('typing.Iterable', [AnyType()])
@@ -3113,9 +3123,10 @@ def lookup_qualified(self, name: str, ctx: Context) -> SymbolTableNode:
31133123
return n
31143124

31153125
def builtin_type(self, fully_qualified_name: str) -> Instance:
3116-
node = self.lookup_fully_qualified(fully_qualified_name)
3117-
assert isinstance(node.node, TypeInfo)
3118-
return Instance(node.node, [])
3126+
sym = self.lookup_fully_qualified(fully_qualified_name)
3127+
node = sym.node
3128+
assert isinstance(node, TypeInfo)
3129+
return Instance(node, [AnyType()] * len(node.defn.type_vars))
31193130

31203131
def lookup_fully_qualified(self, name: str) -> SymbolTableNode:
31213132
"""Lookup a fully qualified name.
@@ -3673,8 +3684,12 @@ def fail_blocker(self, msg: str, ctx: Context) -> None:
36733684
def builtin_type(self, name: str, args: List[Type] = None) -> Instance:
36743685
names = self.modules['builtins']
36753686
sym = names.names[name]
3676-
assert isinstance(sym.node, TypeInfo)
3677-
return Instance(sym.node, args or [])
3687+
node = sym.node
3688+
assert isinstance(node, TypeInfo)
3689+
if args:
3690+
# TODO: assert len(args) == len(node.defn.type_vars)
3691+
return Instance(node, args)
3692+
return Instance(node, [AnyType()] * len(node.defn.type_vars))
36783693

36793694

36803695
def replace_implicit_first_type(sig: FunctionLike, new: Type) -> FunctionLike:

test-data/unit/check-async-await.test

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ async def f() -> int:
8484
x = await g()
8585
return x
8686
[out]
87-
main:7: error: Incompatible types in await (actual type Generator[int, None, str], expected type "Awaitable")
87+
main:7: error: Incompatible types in await (actual type Generator[int, None, str], expected type Awaitable[Any])
8888

8989
[case testAwaitIteratorError]
9090

@@ -95,7 +95,7 @@ async def f() -> int:
9595
x = await g()
9696
return x
9797
[out]
98-
main:6: error: Incompatible types in await (actual type Iterator[Any], expected type "Awaitable")
98+
main:6: error: Incompatible types in await (actual type Iterator[Any], expected type Awaitable[Any])
9999

100100
[case testAwaitArgumentError]
101101

@@ -106,7 +106,7 @@ async def f() -> int:
106106
return x
107107
[builtins fixtures/async_await.pyi]
108108
[out]
109-
main:5: error: Incompatible types in await (actual type "int", expected type "Awaitable")
109+
main:5: error: Incompatible types in await (actual type "int", expected type Awaitable[Any])
110110

111111
[case testAwaitResultError]
112112

@@ -271,7 +271,7 @@ class C:
271271
def __aenter__(self) -> int: pass
272272
async def __aexit__(self, x, y, z) -> None: pass
273273
async def f() -> None:
274-
async with C() as x: # E: Incompatible types in "async with" for __aenter__ (actual type "int", expected type "Awaitable")
274+
async with C() as x: # E: Incompatible types in "async with" for __aenter__ (actual type "int", expected type Awaitable[Any])
275275
pass
276276
[builtins fixtures/async_await.pyi]
277277
[out]
@@ -293,7 +293,7 @@ class C:
293293
async def __aenter__(self) -> int: pass
294294
def __aexit__(self, x, y, z) -> int: pass
295295
async def f() -> None:
296-
async with C() as x: # E: Incompatible types in "async with" for __aexit__ (actual type "int", expected type "Awaitable")
296+
async with C() as x: # E: Incompatible types in "async with" for __aexit__ (actual type "int", expected type Awaitable[Any])
297297
pass
298298
[builtins fixtures/async_await.pyi]
299299
[out]
@@ -615,11 +615,11 @@ def plain_host_generator() -> Generator[str, None, None]:
615615

616616
async def plain_host_coroutine() -> None:
617617
x = 0
618-
x = await plain_generator() # E: Incompatible types in await (actual type Generator[str, None, int], expected type "Awaitable")
618+
x = await plain_generator() # E: Incompatible types in await (actual type Generator[str, None, int], expected type Awaitable[Any])
619619
x = await plain_coroutine()
620620
x = await decorated_generator()
621621
x = await decorated_coroutine()
622-
x = await other_iterator() # E: Incompatible types in await (actual type "It", expected type "Awaitable")
622+
x = await other_iterator() # E: Incompatible types in await (actual type "It", expected type Awaitable[Any])
623623
x = await other_coroutine()
624624

625625
@coroutine
@@ -636,11 +636,11 @@ def decorated_host_generator() -> Generator[str, None, None]:
636636
@coroutine
637637
async def decorated_host_coroutine() -> None:
638638
x = 0
639-
x = await plain_generator() # E: Incompatible types in await (actual type Generator[str, None, int], expected type "Awaitable")
639+
x = await plain_generator() # E: Incompatible types in await (actual type Generator[str, None, int], expected type Awaitable[Any])
640640
x = await plain_coroutine()
641641
x = await decorated_generator()
642642
x = await decorated_coroutine()
643-
x = await other_iterator() # E: Incompatible types in await (actual type "It", expected type "Awaitable")
643+
x = await other_iterator() # E: Incompatible types in await (actual type "It", expected type Awaitable[Any])
644644
x = await other_coroutine()
645645

646646
[builtins fixtures/async_await.pyi]

test-data/unit/fixtures/list.pyi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class list(Iterable[T], Generic[T]):
2323
def append(self, x: T) -> None: pass
2424
def extend(self, x: Iterable[T]) -> None: pass
2525

26-
class tuple: pass
26+
class tuple(Generic[T]): pass
2727
class function: pass
2828
class int: pass
2929
class float: pass

0 commit comments

Comments
 (0)