Skip to content

Commit c295f0c

Browse files
OddBlokeilevkivskyi
authored andcommitted
Erase typevars of generic types when used in Type[C] (#3833)
Prior to this commit, when generic types are used as the C in a Type[C] expression, they don't have their typevars substituted; this leads to the internal type variables of their implementations leaking out in a way that makes them difficult to use. Instead, we now erase those typevars to Any. This fixes #3824.
1 parent fc9fa61 commit c295f0c

File tree

2 files changed

+15
-0
lines changed

2 files changed

+15
-0
lines changed

mypy/checkexpr.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,10 @@ def analyze_ref_expr(self, e: RefExpr, lvalue: bool = False) -> Type:
154154
elif isinstance(node, TypeInfo):
155155
# Reference to a type object.
156156
result = type_object_type(node, self.named_type)
157+
if isinstance(self.type_context[-1], TypeType):
158+
# This is the type in a Type[] expression, so substitute type
159+
# variables with Any.
160+
result = erasetype.erase_typevars(result)
157161
elif isinstance(node, MypyFile):
158162
# Reference to a module object.
159163
try:

test-data/unit/check-classes.test

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3373,6 +3373,17 @@ reveal_type(f(e1t)) # E: Revealed type is '__main__.A'
33733373

33743374
reveal_type(f('')) # E: Revealed type is 'builtins.str'
33753375

3376+
[case testTypeCErasesGenericsFromC]
3377+
from typing import Generic, Type, TypeVar
3378+
3379+
K = TypeVar('K')
3380+
V = TypeVar('V')
3381+
class ExampleDict(Generic[K, V]): ...
3382+
3383+
D = TypeVar('D')
3384+
def mkdict(dict_type: Type[D]) -> D: ...
3385+
reveal_type(mkdict(ExampleDict)) # E: Revealed type is '__main__.ExampleDict*[Any, Any]'
3386+
33763387
-- Synthetic types crashes
33773388
-- -----------------------
33783389

0 commit comments

Comments
 (0)