Skip to content

Remove python2 specific logic for raise keyword check #13242

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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