Skip to content

Commit 37e9a98

Browse files
patrickw276msullivan
authored andcommitted
Fix some issues with raise and clean up checking code (#7515)
Fixes #7514
1 parent 6c4599d commit 37e9a98

File tree

3 files changed

+27
-22
lines changed

3 files changed

+27
-22
lines changed

mypy/checker.py

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3097,31 +3097,18 @@ def visit_raise_stmt(self, s: RaiseStmt) -> None:
30973097
def type_check_raise(self, e: Expression, s: RaiseStmt,
30983098
optional: bool = False) -> None:
30993099
typ = get_proper_type(self.expr_checker.accept(e))
3100-
if isinstance(typ, TypeType):
3101-
if isinstance(typ.item, AnyType):
3102-
return
3103-
typ = typ.item
3104-
if isinstance(typ, FunctionLike):
3105-
if typ.is_type_obj():
3106-
# Cases like "raise/from ExceptionClass".
3107-
typeinfo = typ.type_object()
3108-
base = self.lookup_typeinfo('builtins.BaseException')
3109-
if base in typeinfo.mro or typeinfo.fallback_to_any:
3110-
# Good!
3111-
return
3112-
# Else fall back to the checks below (which will fail).
3113-
if isinstance(typ, TupleType) and self.options.python_version[0] == 2:
3100+
exc_type = self.named_type('builtins.BaseException')
3101+
expected_type = UnionType([exc_type, TypeType(exc_type)])
3102+
if optional:
3103+
expected_type.items.append(NoneType())
3104+
if self.options.python_version[0] == 2:
31143105
# allow `raise type, value, traceback`
31153106
# https://docs.python.org/2/reference/simple_stmts.html#the-raise-statement
31163107
# TODO: Also check tuple item types.
3117-
if len(typ.items) in (2, 3):
3118-
return
3119-
if isinstance(typ, Instance) and typ.type.fallback_to_any:
3120-
# OK!
3121-
return
3122-
expected_type = self.named_type('builtins.BaseException') # type: Type
3123-
if optional:
3124-
expected_type = UnionType([expected_type, NoneType()])
3108+
any_type = AnyType(TypeOfAny.implementation_artifact)
3109+
tuple_type = self.named_type('builtins.tuple')
3110+
expected_type.items.append(TupleType([any_type, any_type], tuple_type))
3111+
expected_type.items.append(TupleType([any_type, any_type, any_type], tuple_type))
31253112
self.check_subtype(typ, expected_type, s, message_registry.INVALID_EXCEPTION)
31263113

31273114
def visit_try_stmt(self, s: TryStmt) -> None:

test-data/unit/check-python2.test

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ raise BaseException, "a"
6868
raise BaseException, "a", None
6969
[builtins_py2 fixtures/exception.pyi]
7070

71+
[case testRaiseTupleTypeFail]
72+
import typing
73+
x = None # type: typing.Type[typing.Tuple[typing.Any, typing.Any, typing.Any]]
74+
raise x # E: Exception must be derived from BaseException
75+
[builtins_py2 fixtures/exception.pyi]
76+
7177
[case testTryExceptWithTuple]
7278
try:
7379
None

test-data/unit/check-statements.test

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,18 @@ x = int # type: typing.Type[int]
422422
raise x # E: Exception must be derived from BaseException
423423
[builtins fixtures/exception.pyi]
424424

425+
[case testRaiseUnion]
426+
import typing
427+
x = None # type: typing.Union[BaseException, typing.Type[BaseException]]
428+
raise x
429+
[builtins fixtures/exception.pyi]
430+
431+
[case testRaiseNonExceptionUnionFails]
432+
import typing
433+
x = None # type: typing.Union[BaseException, int]
434+
raise x # E: Exception must be derived from BaseException
435+
[builtins fixtures/exception.pyi]
436+
425437
[case testRaiseFromStatement]
426438
e = None # type: BaseException
427439
f = None # type: MyError

0 commit comments

Comments
 (0)