You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 00:45:53 +08:00
Better 2.6 tryifelse detection
This commit is contained in:
@@ -23,3 +23,19 @@ def call(*args):
|
||||
except TypeError:
|
||||
# Unhashable argument
|
||||
return 3
|
||||
|
||||
|
||||
# From 2.6.9 pdb.py
|
||||
# Here we have a "try/except" inside a "try/except/else and we can't
|
||||
# distinguish which COME_FROM comes from which "try".
|
||||
|
||||
def do_jump(self, arg):
|
||||
try:
|
||||
arg(1)
|
||||
except ValueError:
|
||||
arg(2)
|
||||
else:
|
||||
try:
|
||||
arg(3)
|
||||
except ValueError:
|
||||
arg(4)
|
||||
|
@@ -315,7 +315,7 @@ class Python26Parser(Python2Parser):
|
||||
self.check_reduce['and'] = 'AST'
|
||||
self.check_reduce['list_for'] = 'AST'
|
||||
self.check_reduce['try_except'] = 'tokens'
|
||||
self.check_reduce['tryelsestmt'] = 'tokens'
|
||||
self.check_reduce['tryelsestmt'] = 'AST'
|
||||
|
||||
def reduce_is_invalid(self, rule, ast, tokens, first, last):
|
||||
invalid = super(Python26Parser,
|
||||
@@ -365,29 +365,49 @@ class Python26Parser(Python2Parser):
|
||||
return (tokens[last-3].kind not in frozenset(('JUMP_FORWARD', 'RETURN_VALUE'))
|
||||
or (tokens[last-3] == 'JUMP_FORWARD' and tokens[last-3].attr != 2))
|
||||
elif rule[0] == 'tryelsestmt':
|
||||
|
||||
# We need to distingush try_except from tryelsestmt and we do that
|
||||
# by checking the jump before the END_FINALLY
|
||||
# If we have:
|
||||
# insn
|
||||
# POP_TOP
|
||||
# END_FINALLY
|
||||
# COME_FROM
|
||||
# then insn is neither a JUMP_FORWARD nor RETURN_VALUE,
|
||||
# or if it is JUMP_FORWARD, then it can't be a JUMP_FORWARD to right after
|
||||
# COME_FROM
|
||||
if last == len(tokens):
|
||||
last -= 1
|
||||
while tokens[last-1] == 'COME_FROM' and tokens[last-2] == 'COME_FROM':
|
||||
last -= 1
|
||||
if tokens[last] == 'COME_FROM' and tokens[last-1] == 'COME_FROM':
|
||||
last -= 1
|
||||
if (tokens[last] == 'COME_FROM'
|
||||
and tokens[last-1] == 'END_FINALLY'
|
||||
and tokens[last-2] == 'POP_TOP'):
|
||||
# A jump of 2 is a jump around POP_TOP, END_FINALLY which
|
||||
# would indicate try/else rather than try
|
||||
return (tokens[last-3].kind in frozenset(('JUMP_FORWARD', 'RETURN_VALUE'))
|
||||
and (tokens[last-3] != 'JUMP_FORWARD' or tokens[last-3].attr == 2))
|
||||
# by making sure that the jump before the except handler jumps to
|
||||
# code somewhere before the end of the construct.
|
||||
# This AST method is slower, but more correct than what we had
|
||||
# which is given after this.
|
||||
|
||||
if ast[3] == 'except_handler':
|
||||
except_handler = ast[3]
|
||||
if except_handler[0] == 'JUMP_FORWARD':
|
||||
else_start = int(except_handler[0].pattr)
|
||||
if last == len(tokens):
|
||||
last -= 1
|
||||
if tokens[last] == 'COME_FROM' and isinstance:
|
||||
last_offset = int(tokens[last].offset.split('_')[0])
|
||||
return else_start >= last_offset
|
||||
|
||||
# Before we resorted to using the AST here is the more hacky way we
|
||||
# did things. This fails with a "try" embedded inside a "try/else"
|
||||
# since we can't detect COME_FROM boundaries.
|
||||
# # We need to distinguish try_except from tryelsestmt and we do that
|
||||
# # by checking the jump before the END_FINALLY
|
||||
# # If we have:
|
||||
# # insn
|
||||
# # POP_TOP
|
||||
# # END_FINALLY
|
||||
# # COME_FROM
|
||||
# # then insn is neither a JUMP_FORWARD nor RETURN_VALUE,
|
||||
# # or if it is JUMP_FORWARD, then it can't be a JUMP_FORWARD to right after
|
||||
# # COME_FROM
|
||||
# if last == len(tokens):
|
||||
# last -= 1
|
||||
# while tokens[last-1] == 'COME_FROM' and tokens[last-2] == 'COME_FROM':
|
||||
# last -= 1
|
||||
# if tokens[last] == 'COME_FROM' and tokens[last-1] == 'COME_FROM':
|
||||
# last -= 1
|
||||
# if (tokens[last] == 'COME_FROM'
|
||||
# and tokens[last-1] == 'END_FINALLY'
|
||||
# and tokens[last-2] == 'POP_TOP'):
|
||||
# # A jump of 2 is a jump around POP_TOP, END_FINALLY which
|
||||
# # would indicate try/else rather than try
|
||||
# return (tokens[last-3].kind in frozenset(('JUMP_FORWARD', 'RETURN_VALUE'))
|
||||
# and (tokens[last-3] != 'JUMP_FORWARD' or tokens[last-3].attr == 2))
|
||||
|
||||
|
||||
return False
|
||||
|
Reference in New Issue
Block a user