From 8ac6c455e7e37b0e1a5faccd9caf91f9948df339 Mon Sep 17 00:00:00 2001 From: Daniel Watkins Date: Tue, 15 Aug 2017 17:55:00 -0400 Subject: [PATCH] Erase typevars of generic types when used in Type[C] 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. --- mypy/checkexpr.py | 4 ++++ test-data/unit/check-classes.test | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 4ac17c373c3f..5658b7b0e2c8 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -154,6 +154,10 @@ def analyze_ref_expr(self, e: RefExpr, lvalue: bool = False) -> Type: elif isinstance(node, TypeInfo): # Reference to a type object. result = type_object_type(node, self.named_type) + if isinstance(self.type_context[-1], TypeType): + # This is the type in a Type[] expression, so substitute type + # variables with Any. + result = erasetype.erase_typevars(result) elif isinstance(node, MypyFile): # Reference to a module object. try: diff --git a/test-data/unit/check-classes.test b/test-data/unit/check-classes.test index 7d7f0fa2ddd6..629ef746f744 100644 --- a/test-data/unit/check-classes.test +++ b/test-data/unit/check-classes.test @@ -3373,6 +3373,17 @@ reveal_type(f(e1t)) # E: Revealed type is '__main__.A' reveal_type(f('')) # E: Revealed type is 'builtins.str' +[case testTypeCErasesGenericsFromC] +from typing import Generic, Type, TypeVar + +K = TypeVar('K') +V = TypeVar('V') +class ExampleDict(Generic[K, V]): ... + +D = TypeVar('D') +def mkdict(dict_type: Type[D]) -> D: ... +reveal_type(mkdict(ExampleDict)) # E: Revealed type is '__main__.ExampleDict*[Any, Any]' + -- Synthetic types crashes -- -----------------------