Skip to content

Commit

Permalink
Remove python2 specific logic for raise keyword check (#13242)
Browse files Browse the repository at this point in the history
  • Loading branch information
sobolevn authored Jul 27, 2022
1 parent 5f85898 commit 1a65c1d
Show file tree
Hide file tree
Showing 3 changed files with 1 addition and 84 deletions.
77 changes: 0 additions & 77 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -4118,13 +4118,6 @@ def type_check_raise(self, e: Expression, s: RaiseStmt, optional: bool = False)
self.msg.deleted_as_rvalue(typ, e)
return

if self.options.python_version[0] == 2:
# Since `raise` has very different rule on python2, we use a different helper.
# https://github.com/python/mypy/pull/11289
self._type_check_raise_python2(e, s, typ)
return

# Python3 case:
exc_type = self.named_type("builtins.BaseException")
expected_type_items = [exc_type, TypeType(exc_type)]
if optional:
Expand All @@ -4140,76 +4133,6 @@ def type_check_raise(self, e: Expression, s: RaiseStmt, optional: bool = False)
# https://github.com/python/mypy/issues/11089
self.expr_checker.check_call(typ, [], [], e)

def _type_check_raise_python2(self, e: Expression, s: RaiseStmt, typ: ProperType) -> None:
# Python2 has two possible major cases:
# 1. `raise expr`, where `expr` is some expression, it can be:
# - Exception typ
# - Exception instance
# - Old style class (not supported)
# - Tuple, where 0th item is exception type or instance
# 2. `raise exc, msg, traceback`, where:
# - `exc` is exception type (not instance!)
# - `traceback` is `types.TracebackType | None`
# Important note: `raise exc, msg` is not the same as `raise (exc, msg)`
# We call `raise exc, msg, traceback` - legacy mode.
exc_type = self.named_type("builtins.BaseException")
exc_inst_or_type = UnionType([exc_type, TypeType(exc_type)])

if not s.legacy_mode and (
isinstance(typ, TupleType)
and typ.items
or (isinstance(typ, Instance) and typ.args and typ.type.fullname == "builtins.tuple")
):
# `raise (exc, ...)` case:
item = typ.items[0] if isinstance(typ, TupleType) else typ.args[0]
self.check_subtype(
item,
exc_inst_or_type,
s,
"When raising a tuple, first element must by derived from BaseException",
)
return
elif s.legacy_mode:
# `raise Exception, msg` case
# `raise Exception, msg, traceback` case
# https://docs.python.org/2/reference/simple_stmts.html#the-raise-statement
assert isinstance(typ, TupleType) # Is set in fastparse2.py
if len(typ.items) >= 2 and isinstance(get_proper_type(typ.items[1]), NoneType):
expected_type: Type = exc_inst_or_type
else:
expected_type = TypeType(exc_type)
self.check_subtype(
typ.items[0], expected_type, s, f'Argument 1 must be "{expected_type}" subtype'
)

# Typecheck `traceback` part:
if len(typ.items) == 3:
# Now, we typecheck `traceback` argument if it is present.
# We do this after the main check for better error message
# and better ordering: first about `BaseException` subtype,
# then about `traceback` type.
traceback_type = UnionType.make_union(
[self.named_type("types.TracebackType"), NoneType()]
)
self.check_subtype(
typ.items[2],
traceback_type,
s,
f'Argument 3 must be "{traceback_type}" subtype',
)
else:
expected_type_items = [
# `raise Exception` and `raise Exception()` cases:
exc_type,
TypeType(exc_type),
]
self.check_subtype(
typ,
UnionType.make_union(expected_type_items),
s,
message_registry.INVALID_EXCEPTION,
)

def visit_try_stmt(self, s: TryStmt) -> None:
"""Type check a try statement."""
# Our enclosing frame will get the result if the try/except falls through.
Expand Down
3 changes: 0 additions & 3 deletions mypy/fastparse2.py
Original file line number Diff line number Diff line change
Expand Up @@ -767,21 +767,18 @@ def visit_With(self, n: ast27.With) -> WithStmt:

# 'raise' [test [',' test [',' test]]]
def visit_Raise(self, n: ast27.Raise) -> RaiseStmt:
legacy_mode = False
if n.type is None:
e = None
else:
if n.inst is None:
e = self.visit(n.type)
else:
legacy_mode = True
if n.tback is None:
e = TupleExpr([self.visit(n.type), self.visit(n.inst)])
else:
e = TupleExpr([self.visit(n.type), self.visit(n.inst), self.visit(n.tback)])

stmt = RaiseStmt(e, None)
stmt.legacy_mode = legacy_mode
return self.set_line(stmt, n)

# TryExcept(stmt* body, excepthandler* handlers, stmt* orelse)
Expand Down
5 changes: 1 addition & 4 deletions mypy/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1424,19 +1424,16 @@ def accept(self, visitor: StatementVisitor[T]) -> T:


class RaiseStmt(Statement):
__slots__ = ("expr", "from_expr", "legacy_mode")
__slots__ = ("expr", "from_expr")

# Plain 'raise' is a valid statement.
expr: Optional[Expression]
from_expr: Optional[Expression]
# Is set when python2 has `raise exc, msg, traceback`.
legacy_mode: bool

def __init__(self, expr: Optional[Expression], from_expr: Optional[Expression]) -> None:
super().__init__()
self.expr = expr
self.from_expr = from_expr
self.legacy_mode = False

def accept(self, visitor: StatementVisitor[T]) -> T:
return visitor.visit_raise_stmt(self)
Expand Down

0 comments on commit 1a65c1d

Please sign in to comment.