@@ -3492,7 +3492,7 @@ def visit_raise_stmt(self, s: RaiseStmt) -> None:
3492
3492
if s .expr :
3493
3493
self .type_check_raise (s .expr , s )
3494
3494
if s .from_expr :
3495
- self .type_check_raise (s .from_expr , s , optional = True )
3495
+ self .type_check_raise (s .from_expr , s , True )
3496
3496
self .binder .unreachable ()
3497
3497
3498
3498
def type_check_raise (self , e : Expression , s : RaiseStmt ,
@@ -3501,88 +3501,24 @@ def type_check_raise(self, e: Expression, s: RaiseStmt,
3501
3501
if isinstance (typ , DeletedType ):
3502
3502
self .msg .deleted_as_rvalue (typ , e )
3503
3503
return
3504
-
3505
- if self .options .python_version [0 ] == 2 :
3506
- # Since `raise` has very different rule on python2, we use a different helper.
3507
- # https://github.com/python/mypy/pull/11289
3508
- self ._type_check_raise_python2 (e , s , typ )
3509
- return
3510
-
3511
- # Python3 case:
3512
3504
exc_type = self .named_type ('builtins.BaseException' )
3513
- expected_type_items = [exc_type , TypeType (exc_type )]
3505
+ expected_type = UnionType ( [exc_type , TypeType (exc_type )])
3514
3506
if optional :
3515
- # This is used for `x` part in a case like `raise e from x`,
3516
- # where we allow `raise e from None`.
3517
- expected_type_items .append (NoneType ())
3518
-
3519
- self .check_subtype (
3520
- typ , UnionType .make_union (expected_type_items ), s ,
3521
- message_registry .INVALID_EXCEPTION ,
3522
- )
3507
+ expected_type .items .append (NoneType ())
3508
+ if self .options .python_version [0 ] == 2 :
3509
+ # allow `raise type, value, traceback`
3510
+ # https://docs.python.org/2/reference/simple_stmts.html#the-raise-statement
3511
+ # TODO: Also check tuple item types.
3512
+ any_type = AnyType (TypeOfAny .implementation_artifact )
3513
+ tuple_type = self .named_type ('builtins.tuple' )
3514
+ expected_type .items .append (TupleType ([any_type , any_type ], tuple_type ))
3515
+ expected_type .items .append (TupleType ([any_type , any_type , any_type ], tuple_type ))
3516
+ self .check_subtype (typ , expected_type , s , message_registry .INVALID_EXCEPTION )
3523
3517
3524
3518
if isinstance (typ , FunctionLike ):
3525
3519
# https://github.com/python/mypy/issues/11089
3526
3520
self .expr_checker .check_call (typ , [], [], e )
3527
3521
3528
- def _type_check_raise_python2 (self , e : Expression , s : RaiseStmt , typ : ProperType ) -> None :
3529
- # Python2 has two possible major cases:
3530
- # 1. `raise expr`, where `expr` is some expression, it can be:
3531
- # - Exception typ
3532
- # - Exception instance
3533
- # - Old style class (not supported)
3534
- # - Tuple, where 0th item is exception type or instance
3535
- # 2. `raise exc, msg, traceback`, where:
3536
- # - `exc` is exception type (not instance!)
3537
- # - `traceback` is `types.TracebackType | None`
3538
- # Important note: `raise exc, msg` is not the same as `raise (exc, msg)`
3539
- # We call `raise exc, msg, traceback` - legacy mode.
3540
- exc_type = self .named_type ('builtins.BaseException' )
3541
-
3542
- if (not s .legacy_mode and (isinstance (typ , TupleType ) and typ .items
3543
- or (isinstance (typ , Instance ) and typ .args
3544
- and typ .type .fullname == 'builtins.tuple' ))):
3545
- # `raise (exc, ...)` case:
3546
- item = typ .items [0 ] if isinstance (typ , TupleType ) else typ .args [0 ]
3547
- self .check_subtype (
3548
- item , UnionType ([exc_type , TypeType (exc_type )]), s ,
3549
- 'When raising a tuple, first element must by derived from BaseException' ,
3550
- )
3551
- return
3552
- elif s .legacy_mode :
3553
- # `raise Exception, msg` case
3554
- # `raise Exception, msg, traceback` case
3555
- # https://docs.python.org/2/reference/simple_stmts.html#the-raise-statement
3556
- assert isinstance (typ , TupleType ) # Is set in fastparse2.py
3557
- self .check_subtype (
3558
- typ .items [0 ], TypeType (exc_type ), s ,
3559
- 'First argument must be BaseException subtype' ,
3560
- )
3561
-
3562
- # Typecheck `traceback` part:
3563
- if len (typ .items ) == 3 :
3564
- # Now, we typecheck `traceback` argument if it is present.
3565
- # We do this after the main check for better error message
3566
- # and better ordering: first about `BaseException` subtype,
3567
- # then about `traceback` type.
3568
- traceback_type = UnionType .make_union ([
3569
- self .named_type ('types.TracebackType' ),
3570
- NoneType (),
3571
- ])
3572
- self .check_subtype (
3573
- typ .items [2 ], traceback_type , s ,
3574
- 'Third argument to raise must have "{}" type' .format (traceback_type ),
3575
- )
3576
- else :
3577
- expected_type_items = [
3578
- # `raise Exception` and `raise Exception()` cases:
3579
- exc_type , TypeType (exc_type ),
3580
- ]
3581
- self .check_subtype (
3582
- typ , UnionType .make_union (expected_type_items ),
3583
- s , message_registry .INVALID_EXCEPTION ,
3584
- )
3585
-
3586
3522
def visit_try_stmt (self , s : TryStmt ) -> None :
3587
3523
"""Type check a try statement."""
3588
3524
# Our enclosing frame will get the result if the try/except falls through.
0 commit comments