You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 00:45:53 +08:00
Towards Python3 getting try/except working more often.
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -19,3 +19,23 @@ except ImportError:
|
||||
x = 3
|
||||
finally:
|
||||
x = 4
|
||||
|
||||
# Tests Python3:
|
||||
# trystmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK try_middle come_froms
|
||||
# come_froms ::= COME_FROM COME_FROM
|
||||
# START ::= |- stmts
|
||||
# stmts ::= sstmt
|
||||
# sstmt ::= stmt
|
||||
# stmt ::= trystmt
|
||||
# trystmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK try_middle come_froms
|
||||
# come_froms ::= COME_FROM
|
||||
# try_middle ::= JUMP_FORWARD COME_FROM except_stmts END_FINALLY COME_FROM
|
||||
# Python2 doesn't have the come_froms (which allows for 3 successive COME_FROMs)
|
||||
# it does place 2 COME_FROMs at the end of this code.
|
||||
|
||||
try:
|
||||
x = 1
|
||||
except SystemExit:
|
||||
x = 2
|
||||
except:
|
||||
x = 3
|
||||
|
@@ -76,6 +76,8 @@ for vers in (2.5, 2.6, 2.7, 3.2, 3.3, 3.4):
|
||||
test_options[key] = (bytecode, PYC, bytecode, vers)
|
||||
key = "%s" % vers
|
||||
pythonlib = "python%s" % vers
|
||||
if vers >= 3.0:
|
||||
pythonlib = os.path.join(pythonlib, '__pycache__')
|
||||
test_options[key] = (os.path.join(lib_prefix, pythonlib), PYC, pythonlib, vers)
|
||||
|
||||
#-----
|
||||
|
@@ -228,8 +228,7 @@ class Python3Parser(PythonParser):
|
||||
'''
|
||||
|
||||
def p_grammar(self, args):
|
||||
'''
|
||||
stmts ::= stmts sstmt
|
||||
'''stmts ::= stmts sstmt
|
||||
stmts ::= sstmt
|
||||
sstmt ::= stmt
|
||||
sstmt ::= ifelsestmtr
|
||||
@@ -405,6 +404,10 @@ class Python3Parser(PythonParser):
|
||||
testfalse ::= expr jmp_false
|
||||
testtrue ::= expr jmp_true
|
||||
|
||||
come_froms :: = COME_FROM COME_FROM
|
||||
come_froms :: = COME_FROM
|
||||
|
||||
|
||||
_ifstmts_jump ::= return_if_stmts
|
||||
_ifstmts_jump ::= c_stmts_opt JUMP_FORWARD COME_FROM _come_from
|
||||
|
||||
@@ -421,8 +424,16 @@ class Python3Parser(PythonParser):
|
||||
ifelsestmtl ::= testexpr c_stmts_opt JUMP_BACK else_suitel
|
||||
|
||||
|
||||
# FIXME: this feels like a hack. Is it just 1 or two
|
||||
# COME_FROMs? the parsed tree for this and even with just the
|
||||
# one COME_FROM for Python 2.7 seems to associate the
|
||||
# COME_FROM targets from the wrong places
|
||||
|
||||
come_froms ::= COME_FROM COME_FROM
|
||||
come_froms ::= COME_FROM
|
||||
|
||||
trystmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
|
||||
try_middle COME_FROM
|
||||
try_middle come_froms
|
||||
|
||||
# this is nested inside a trystmt
|
||||
tryfinallystmt ::= SETUP_FINALLY suite_stmts
|
||||
@@ -450,6 +461,7 @@ class Python3Parser(PythonParser):
|
||||
except_stmt ::= except_cond2 except_suite
|
||||
except_stmt ::= except_cond2 except_suite_finalize
|
||||
except_stmt ::= except
|
||||
except_stmt ::= except_pop_except
|
||||
|
||||
# Python3 introduced POP_EXCEPT
|
||||
except_suite ::= c_stmts_opt POP_EXCEPT JUMP_FORWARD
|
||||
@@ -471,11 +483,12 @@ class Python3Parser(PythonParser):
|
||||
except_cond2 ::= DUP_TOP expr COMPARE_OP
|
||||
jmp_false POP_TOP designator POP_TOP
|
||||
|
||||
except ::= POP_TOP POP_TOP POP_TOP POP_EXCEPT c_stmts_opt JUMP_FORWARD
|
||||
except ::= POP_TOP POP_TOP POP_TOP c_stmts_opt JUMP_FORWARD
|
||||
except ::= POP_TOP POP_TOP POP_TOP POP_EXCEPT c_stmts_opt jmp_abs
|
||||
except ::= POP_TOP POP_TOP POP_TOP c_stmts_opt POP_EXCEPT JUMP_FORWARD
|
||||
except ::= POP_TOP POP_TOP POP_TOP return_stmts
|
||||
|
||||
except_pop_except ::= POP_TOP POP_TOP POP_TOP POP_EXCEPT c_stmts_opt JUMP_FORWARD
|
||||
except_pop_except ::= POP_TOP POP_TOP POP_TOP POP_EXCEPT c_stmts_opt jmp_abs
|
||||
|
||||
jmp_abs ::= JUMP_ABSOLUTE
|
||||
jmp_abs ::= JUMP_BACK
|
||||
|
||||
|
@@ -618,7 +618,8 @@ class Scanner27(scan.Scanner):
|
||||
for i in self.op_range(0, n):
|
||||
op = code[i]
|
||||
|
||||
# Determine structures and fix jumps for 2.3+
|
||||
# Determine structures and fix jumps in Python versions
|
||||
# since 2.3
|
||||
self.detect_structure(i, op)
|
||||
|
||||
if op >= HAVE_ARGUMENT:
|
||||
|
@@ -313,7 +313,8 @@ class Scanner3(scan.Scanner):
|
||||
for offset in self.op_range(0, codelen):
|
||||
op = code[offset]
|
||||
|
||||
# Determine structures and fix jumps for 2.3+
|
||||
# Determine structures and fix jumps in Python versions
|
||||
# since 2.3
|
||||
self.detect_structure(offset)
|
||||
|
||||
if op >= op3.HAVE_ARGUMENT:
|
||||
@@ -322,7 +323,7 @@ class Scanner3(scan.Scanner):
|
||||
|
||||
if label is None:
|
||||
if op in op3.hasjrel and op != FOR_ITER:
|
||||
label = offset + 3 + oparg
|
||||
label = offset + self.op_size(op) + oparg
|
||||
elif op in op3.hasjabs:
|
||||
if op in (JUMP_IF_FALSE_OR_POP, JUMP_IF_TRUE_OR_POP):
|
||||
if oparg > offset:
|
||||
|
@@ -183,49 +183,7 @@ class Scanner34(scan3.Scanner3):
|
||||
parent = struct
|
||||
pass
|
||||
|
||||
if op == SETUP_EXCEPT:
|
||||
start = offset + 3
|
||||
target = self.get_target(offset)
|
||||
end = self.restrict_to_parent(target, parent)
|
||||
if target != end:
|
||||
self.fixed_jumps[pos] = end
|
||||
# print target, end, parent
|
||||
# Add the try block
|
||||
self.structs.append({'type': 'try',
|
||||
'start': start,
|
||||
'end': end-4})
|
||||
# Now isolate the except and else blocks
|
||||
end_else = start_else = self.get_target(self.prev_op[end])
|
||||
|
||||
# Add the except blocks
|
||||
i = end
|
||||
while self.code[i] != END_FINALLY:
|
||||
jmp = self.next_except_jump(i)
|
||||
if self.code[jmp] == RETURN_VALUE:
|
||||
self.structs.append({'type': 'except',
|
||||
'start': i,
|
||||
'end': jmp+1})
|
||||
i = jmp + 1
|
||||
else:
|
||||
if self.get_target(jmp) != start_else:
|
||||
end_else = self.get_target(jmp)
|
||||
if self.code[jmp] == JUMP_FORWARD:
|
||||
self.fixed_jumps[jmp] = -1
|
||||
self.structs.append({'type': 'except',
|
||||
'start': i,
|
||||
'end': jmp})
|
||||
i = jmp + 3
|
||||
|
||||
# Add the try-else block
|
||||
if end_else != start_else:
|
||||
r_end_else = self.restrict_to_parent(end_else, parent)
|
||||
self.structs.append({'type': 'try-else',
|
||||
'start': i+1,
|
||||
'end': r_end_else})
|
||||
self.fixed_jumps[i] = r_end_else
|
||||
else:
|
||||
self.fixed_jumps[i] = i+1
|
||||
elif op in (POP_JUMP_IF_FALSE, POP_JUMP_IF_TRUE):
|
||||
if op in (POP_JUMP_IF_FALSE, POP_JUMP_IF_TRUE):
|
||||
start = offset + self.op_size(op)
|
||||
target = self.get_target(offset)
|
||||
rtarget = self.restrict_to_parent(target, parent)
|
||||
|
@@ -317,6 +317,8 @@ TABLE_DIRECT = {
|
||||
'tryelsestmtl': ( '%|try:\n%+%c%-%c%|else:\n%+%c%-', 1, 3, 4 ),
|
||||
'tf_trystmt': ( '%c%-%c%+', 1, 3 ),
|
||||
'tf_tryelsestmt': ( '%c%-%c%|else:\n%+%c', 1, 3, 4 ),
|
||||
'except': ('%|except:\n%+%c%-', 3 ),
|
||||
'except_pop_except': ('%|except:\n%+%c%-', 4 ),
|
||||
'except_cond1': ( '%|except %c:\n', 1 ),
|
||||
'except_cond2': ( '%|except %c as %c:\n', 1, 5 ),
|
||||
'except_suite': ( '%+%c%-%C', 0, (1, maxint, '') ),
|
||||
@@ -503,12 +505,6 @@ class Walker(GenericASTTraversal, object):
|
||||
self.pending_newlines = 0
|
||||
self.hide_internal = True
|
||||
|
||||
if version >= 3.0:
|
||||
# Python 3 adds a POP_EXCEPT instruction
|
||||
TABLE_DIRECT['except'] = ('%|except:\n%+%c%-', 4 )
|
||||
else:
|
||||
TABLE_DIRECT['except'] = ('%|except:\n%+%c%-', 3 )
|
||||
pass
|
||||
return
|
||||
|
||||
f = property(lambda s: s.params['f'],
|
||||
@@ -1251,7 +1247,6 @@ class Walker(GenericASTTraversal, object):
|
||||
# self.print_("-----")
|
||||
# self.print(startnode)
|
||||
|
||||
|
||||
fmt = entry[0]
|
||||
arg = 1
|
||||
i = 0
|
||||
|
Reference in New Issue
Block a user