Files
python-uncompyle6/uncompyle6/parsers/reducecheck/tryexcept.py

77 lines
2.6 KiB
Python

# Copyright (c) 2020, 2022, 2024 Rocky Bernstein
def tryexcept(self, lhs, n: int, rule, ast, tokens, first: int, last: int):
come_from_except = ast[-1]
if rule == (
"try_except",
(
"SETUP_EXCEPT",
"suite_stmts_opt",
"POP_BLOCK",
"except_handler",
"opt_come_from_except",
),
):
if come_from_except[0] == "COME_FROM":
# There should be at least two COME_FROMs, one from an
# exception handler and one from the try. Otherwise
# we have a try/else.
return True
pass
elif rule == (
"try_except",
(
"SETUP_EXCEPT",
"suite_stmts_opt",
"POP_BLOCK",
"except_handler",
"COME_FROM",
),
):
return come_from_except.attr < tokens[first].offset
elif rule == (
"try_except",
(
"SETUP_EXCEPT",
"suite_stmts_opt",
"POP_BLOCK",
"except_handler",
"\\e_opt_come_from_except",
),
):
# Find END_FINALLY.
for i in range(last, first, -1):
if tokens[i] == "END_FINALLY":
jump_before_finally = tokens[i - 1]
if jump_before_finally.kind.startswith("JUMP"):
if jump_before_finally == "JUMP_FORWARD":
# If there is a JUMP_FORWARD before
# the END_FINALLY to some jumps place
# beyond tokens[last].off2int() then
# this is a try/else rather than an
# try (no else).
return tokens[i - 1].attr > tokens[last].off2int(
prefer_last=True
)
elif jump_before_finally == "JUMP_BACK":
# If there is a JUMP_BACK before the
# END_FINALLY then this is a looping
# jump, but then jumps in the except
# handlers have to also be a looping
# jump or this is a try/else rather
# than an try (no else).
except_handler = ast[3]
if (
except_handler == "except_handler"
and except_handler[0] == "JUMP_FORWARD"
):
return True
return False
pass
pass
pass
return False