diff --git a/mypy/messages.py b/mypy/messages.py index a5a4ce2542ea..b32c2b282a51 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -392,8 +392,13 @@ def has_no_attr(self, typ: Type, member: str, context: Context) -> Type: self.format(typ)), context) elif member == '__getitem__': # Indexed get. - self.fail('Value of type {} is not indexable'.format( - self.format(typ)), context) + # TODO: Fix this consistently in self.format + if isinstance(typ, CallableType) and typ.is_type_obj(): + self.fail('The type {} is not generic and not indexable'.format( + self.format(typ)), context) + else: + self.fail('Value of type {} is not indexable'.format( + self.format(typ)), context) elif member == '__setitem__': # Indexed set. self.fail('Unsupported target for indexed assignment', context) diff --git a/mypy/semanal.py b/mypy/semanal.py index dd82975585b8..af6ec9be8080 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -2623,7 +2623,7 @@ def visit_index_expr(self, expr: IndexExpr) -> None: expr.base.accept(self) if (isinstance(expr.base, RefExpr) and isinstance(expr.base.node, TypeInfo) - and expr.base.node.is_enum): + and not expr.base.node.is_generic()): expr.index.accept(self) elif isinstance(expr.base, RefExpr) and expr.base.kind == TYPE_ALIAS: # Special form -- subscripting a generic type alias. diff --git a/test-data/unit/check-classes.test b/test-data/unit/check-classes.test index 36cb55ceb215..7e46c6c3f6c8 100644 --- a/test-data/unit/check-classes.test +++ b/test-data/unit/check-classes.test @@ -2883,6 +2883,14 @@ class Concrete(metaclass=Meta): reveal_type(Concrete + X()) # E: Revealed type is 'builtins.str' Concrete + "hello" # E: Unsupported operand types for + ("Meta" and "str") +[case testMetaclassGetitem] +class M(type): + def __getitem__(self, key) -> int: return 1 + +class A(metaclass=M): pass + +reveal_type(A[M]) # E: Revealed type is 'builtins.int' + [case testMetaclassSelftype] from typing import TypeVar, Type diff --git a/test-data/unit/check-generics.test b/test-data/unit/check-generics.test index b42f805bade1..1c0c730b2a2e 100644 --- a/test-data/unit/check-generics.test +++ b/test-data/unit/check-generics.test @@ -449,7 +449,7 @@ A[int, str, int]() # E: Type application has too many types (2 expected) a = None # type: A class A: pass a[A]() # E: Value of type "A" is not indexable -A[A]() # E: Type application targets a non-generic function or class +A[A]() # E: The type "A" is not generic and not indexable [out] [case testTypeApplicationArgTypes] @@ -505,7 +505,7 @@ Alias[int]("a") # E: Argument 1 to "Node" has incompatible type "str"; expected [out] [case testTypeApplicationCrash] -type[int] # this was crashing, see #2302 (comment) # E: Type application targets a non-generic function or class +type[int] # this was crashing, see #2302 (comment) # E: The type "type" is not generic and not indexable [out] diff --git a/test-data/unit/semanal-errors.test b/test-data/unit/semanal-errors.test index aa45dde1faca..8b5eef03d917 100644 --- a/test-data/unit/semanal-errors.test +++ b/test-data/unit/semanal-errors.test @@ -103,13 +103,6 @@ class A: pass x = cast(A[int], 1) # E: "A" expects no type arguments, but 1 given [out] -[case testInvalidNumberOfGenericArgsInTypeApplication] -import typing -class A: pass -class B: pass -x = A[B[int]]() # E: "B" expects no type arguments, but 1 given -[out] - [case testInvalidNumberOfGenericArgsInNestedGenericType] from typing import TypeVar, Generic T = TypeVar('T')