Repository: python/mypy

Issue:
Adding # type: ignore to EnumClass[string_value] doesn't set the type to Any
Example:
```python
from typing import Dict
from enum import Enum
class E(Enum):
    V = 'V'
d = {}  # type: Dict[E, int]
def f(s: str):
    e = E[s]  # type: ignore
    d[e] = 0  # Still error here
```
We have to use `# type: ignore` on the line `e = E[s]` because of #741. But somehow the type of `e`, when ignoring the error, is not `Any` but something else. So on the last line we get
```
__tmp__.py: note: In function "f":
__tmp__.py:8: error: Invalid index type "E" for "dict"
```
The weird thing is that if e had type E, d[e] would be valid, so the error is also somehow lying...

**UPDATE:** When trying to repro this, don't try E['V'] -- mypy sees the literal and gives some other error, probably also because of #741.


Discussion:
This was introduced by 57ff82ba9c44edd5b2517c5861732fea7ae579d5 (PR #2378, Implement generic type aliases). @ilevkivskyi Can you look into this? It would break our internal build (if we were to update mypy).


Resolving patch:
diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py
--- a/mypy/checkexpr.py
+++ b/mypy/checkexpr.py
@@ -1378,6 +1378,9 @@ def visit_type_application(self, tapp: TypeApplication) -> Type:
 
     def visit_type_alias_expr(self, alias: TypeAliasExpr) -> Type:
         """Get type of a type alias (could be generic) in a runtime expression."""
+        if isinstance(alias.type, Instance) and alias.type.invalid:
+            # An invalid alias, error already has been reported
+            return AnyType()
         item = alias.type
         if not alias.in_runtime:
             # We don't replace TypeVar's with Any for alias used as Alias[T](42).
diff --git a/mypy/typeanal.py b/mypy/typeanal.py
--- a/mypy/typeanal.py
+++ b/mypy/typeanal.py
@@ -416,6 +416,7 @@ def visit_instance(self, t: Instance) -> None:
             # otherwise the type checker may crash as it expects
             # things to be right.
             t.args = [AnyType() for _ in info.type_vars]
+            t.invalid = True
         elif info.defn.type_vars:
             # Check type argument values.
             for (i, arg), TypeVar in zip(enumerate(t.args), info.defn.type_vars):
diff --git a/mypy/types.py b/mypy/types.py
--- a/mypy/types.py
+++ b/mypy/types.py
@@ -416,6 +416,7 @@ class Instance(Type):
     type = None  # type: mypy.nodes.TypeInfo
     args = None  # type: List[Type]
     erased = False  # True if result of type variable substitution
+    invalid = False  # True if recovered after incorrect number of type arguments error
 
     def __init__(self, typ: mypy.nodes.TypeInfo, args: List[Type],
                  line: int = -1, column: int = -1, erased: bool = False) -> None:


Test patch:
diff --git a/test-data/unit/check-generics.test b/test-data/unit/check-generics.test
--- a/test-data/unit/check-generics.test
+++ b/test-data/unit/check-generics.test
@@ -970,6 +970,13 @@ main:9:7: error: Type argument 1 of "A" has incompatible value "str"
 main:13: error: Type argument 1 of "A" has incompatible value "str"
 main:13: error: Type argument 2 of "A" has incompatible value "str"
 
+[case testGenericTypeAliasesIgnoredPotentialAlias]
+class A: ...
+Bad = A[int] # type: ignore
+
+reveal_type(Bad) # E: Revealed type is 'Any'
+[out]
+
 
 -- Multiple assignment with lists
 -- ------------------------------