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