Repository: python/mypy

Issue:
tuple excepts fail when one of the classes has type `Any`
``` python
from typing import Any

C = None   # type: Any
try:
    pass
except (C, Exception):
    pass
```

results in
`test.py:6: error: Exception type must be derived from BaseException`



Discussion:
@pdmccormick 

What's the purpose of C in the repro?

--Guido (mobile)
On Jun 3, 2016 12:49 PM, "David Fisher" notifications@github.com wrote:

> @pdmccormick https://github.com/pdmccormick
> 
> —
> You are receiving this because you are subscribed to this thread.
> Reply to this email directly, view it on GitHub
> https://github.com/python/mypy/issues/1635#issuecomment-223677120, or mute
> the thread
> https://github.com/notifications/unsubscribe/ACwrMhiyaIsITaVwrhe1SoIKXast4_nPks5qIIUzgaJpZM4It2ek
> .

I made a slight editing error as I was cleaning the example up.  Fixed.

This was broken in #1610.


Resolving patch:
diff --git a/mypy/checker.py b/mypy/checker.py
--- a/mypy/checker.py
+++ b/mypy/checker.py
@@ -1827,13 +1827,15 @@ def visit_try_stmt(self, s: TryStmt) -> Type:
     def visit_except_handler_test(self, n: Node) -> Type:
         """Type check an exception handler test clause."""
         type = self.accept(n)
-        if isinstance(type, AnyType):
-            return type
 
         all_types = []  # type: List[Type]
         test_types = type.items if isinstance(type, TupleType) else [type]
 
         for ttype in test_types:
+            if isinstance(ttype, AnyType):
+                all_types.append(ttype)
+                continue
+
             if not isinstance(ttype, FunctionLike):
                 self.fail(messages.INVALID_EXCEPTION_TYPE, n)
                 return AnyType()


Test patch:
diff --git a/mypy/test/data/check-statements.test b/mypy/test/data/check-statements.test
--- a/mypy/test/data/check-statements.test
+++ b/mypy/test/data/check-statements.test
@@ -598,6 +598,41 @@ except (E1_1, E1_2) as e2:
     c = e2 # type: E1_2 # E: Incompatible types in assignment (expression has type "Union[E1_1, E1_2]", variable has type "E1_2")
 [builtins fixtures/exception.py]
 
+[case testExceptWithAnyTypes]
+from typing import Any
+
+E1 = None  # type: Any
+class E2(BaseException): pass
+class NotBaseDerived: pass
+
+try:
+    pass
+except BaseException as e1:
+    reveal_type(e1)  # E: Revealed type is 'builtins.BaseException'
+except (E1, BaseException) as e2:
+    reveal_type(e2)  # E: Revealed type is 'Any'
+except (E1, E2) as e3:
+    reveal_type(e3)  # E: Revealed type is 'Any'
+except (E1, E2, BaseException) as e4:
+    reveal_type(e4)  # E: Revealed type is 'Any'
+
+try: pass
+except E1 as e1:
+    reveal_type(e1)  # E: Revealed type is 'Any'
+except E2 as e2:
+    reveal_type(e2)  # E: Revealed type is '__main__.E2'
+except NotBaseDerived as e3:  # E: Exception type must be derived from BaseException
+    pass
+except (NotBaseDerived, E1) as e4:  # E: Exception type must be derived from BaseException
+    pass
+except (NotBaseDerived, E2) as e5:  # E: Exception type must be derived from BaseException
+    pass
+except (NotBaseDerived, E1, E2) as e6:  # E: Exception type must be derived from BaseException
+    pass
+except (E1, E2, NotBaseDerived) as e6:  # E: Exception type must be derived from BaseException
+    pass
+[builtins fixtures/exception.py]
+
 [case testReuseTryExceptionVariable]
 import typing
 class E1(BaseException): pass