Repository: python/mypy

Issue:
Unable to pass in an Exception Type as a parameter
test_exception.py:
```python
from typing import Any, Callable, Type

def allow_exception(ExceptionToCheck: Type[BaseException], f:
                    Callable[[], Any]) -> Any:
    try:
        return f()
    except ExceptionToCheck as e:
        return None
```

Command Line:
```
mypy -s --fast-parser --strict-optional --warn-no-return test_exception.py
```

Result:
```
test_exception.py: note: In function "allow_exception":
test_exception.py:6: error: Exception type must be derived from BaseException
```


Discussion:

Resolving patch:
diff --git a/mypy/checker.py b/mypy/checker.py
--- a/mypy/checker.py
+++ b/mypy/checker.py
@@ -29,7 +29,7 @@
 from mypy import nodes
 from mypy.types import (
     Type, AnyType, CallableType, Void, FunctionLike, Overloaded, TupleType,
-    Instance, NoneTyp, ErrorType, strip_type,
+    Instance, NoneTyp, ErrorType, strip_type, TypeType,
     UnionType, TypeVarId, TypeVarType, PartialType, DeletedType, UninhabitedType,
     true_only, false_only, function_type
 )
@@ -1745,28 +1745,33 @@ def visit_try_without_finally(self, s: TryStmt, try_frame: bool) -> None:
 
     def visit_except_handler_test(self, n: Expression) -> Type:
         """Type check an exception handler test clause."""
-        type = self.accept(n)
+        typ = self.accept(n)
 
         all_types = []  # type: List[Type]
-        test_types = type.items if isinstance(type, TupleType) else [type]
+        test_types = typ.items if isinstance(typ, TupleType) else [typ]
 
         for ttype in test_types:
             if isinstance(ttype, AnyType):
                 all_types.append(ttype)
                 continue
 
-            if not isinstance(ttype, FunctionLike):
+            if isinstance(ttype, FunctionLike):
+                item = ttype.items()[0]
+                if not item.is_type_obj():
+                    self.fail(messages.INVALID_EXCEPTION_TYPE, n)
+                    return AnyType()
+                exc_type = item.ret_type
+            elif isinstance(ttype, TypeType):
+                exc_type = ttype.item
+            else:
                 self.fail(messages.INVALID_EXCEPTION_TYPE, n)
                 return AnyType()
 
-            item = ttype.items()[0]
-            ret_type = item.ret_type
-            if not (is_subtype(ret_type, self.named_type('builtins.BaseException'))
-                    and item.is_type_obj()):
+            if not is_subtype(exc_type, self.named_type('builtins.BaseException')):
                 self.fail(messages.INVALID_EXCEPTION_TYPE, n)
                 return AnyType()
 
-            all_types.append(ret_type)
+            all_types.append(exc_type)
 
         return UnionType.make_simplified_union(all_types)
 


Test patch:
diff --git a/test-data/unit/check-statements.test b/test-data/unit/check-statements.test
--- a/test-data/unit/check-statements.test
+++ b/test-data/unit/check-statements.test
@@ -789,8 +789,6 @@ main: note: In function "f":
 main:10: error: Revealed type is 'builtins.int'
 main:15: error: Revealed type is 'builtins.str'
 
-
-
 [case testArbitraryExpressionAsExceptionType]
 import typing
 a = BaseException
@@ -867,6 +865,26 @@ raise EE()
 raise EE
 [builtins fixtures/exception.pyi]
 
+[case testExceptionIsType]
+from typing import Type
+class B(BaseException): pass
+def f(e: Type[B]):
+    try: pass
+    except e: pass
+def g(e: Type[BaseException]):
+    try: pass
+    except e as err:
+        reveal_type(err)
+def h(e: Type[int]):
+    try: pass
+    except e: pass
+[builtins fixtures/exception.pyi]
+[out]
+main: note: In function "g":
+main:9: error: Revealed type is 'builtins.BaseException'
+main: note: In function "h":
+main:12: error: Exception type must be derived from BaseException
+
 
 -- Del statement
 -- -------------