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
|
x = 3
|
||||||
finally:
|
finally:
|
||||||
x = 4
|
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)
|
test_options[key] = (bytecode, PYC, bytecode, vers)
|
||||||
key = "%s" % vers
|
key = "%s" % vers
|
||||||
pythonlib = "python%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)
|
test_options[key] = (os.path.join(lib_prefix, pythonlib), PYC, pythonlib, vers)
|
||||||
|
|
||||||
#-----
|
#-----
|
||||||
|
@@ -228,8 +228,7 @@ class Python3Parser(PythonParser):
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
def p_grammar(self, args):
|
def p_grammar(self, args):
|
||||||
'''
|
'''stmts ::= stmts sstmt
|
||||||
stmts ::= stmts sstmt
|
|
||||||
stmts ::= sstmt
|
stmts ::= sstmt
|
||||||
sstmt ::= stmt
|
sstmt ::= stmt
|
||||||
sstmt ::= ifelsestmtr
|
sstmt ::= ifelsestmtr
|
||||||
@@ -405,6 +404,10 @@ class Python3Parser(PythonParser):
|
|||||||
testfalse ::= expr jmp_false
|
testfalse ::= expr jmp_false
|
||||||
testtrue ::= expr jmp_true
|
testtrue ::= expr jmp_true
|
||||||
|
|
||||||
|
come_froms :: = COME_FROM COME_FROM
|
||||||
|
come_froms :: = COME_FROM
|
||||||
|
|
||||||
|
|
||||||
_ifstmts_jump ::= return_if_stmts
|
_ifstmts_jump ::= return_if_stmts
|
||||||
_ifstmts_jump ::= c_stmts_opt JUMP_FORWARD COME_FROM _come_from
|
_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
|
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
|
trystmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
|
||||||
try_middle COME_FROM
|
try_middle come_froms
|
||||||
|
|
||||||
# this is nested inside a trystmt
|
# this is nested inside a trystmt
|
||||||
tryfinallystmt ::= SETUP_FINALLY suite_stmts
|
tryfinallystmt ::= SETUP_FINALLY suite_stmts
|
||||||
@@ -450,6 +461,7 @@ class Python3Parser(PythonParser):
|
|||||||
except_stmt ::= except_cond2 except_suite
|
except_stmt ::= except_cond2 except_suite
|
||||||
except_stmt ::= except_cond2 except_suite_finalize
|
except_stmt ::= except_cond2 except_suite_finalize
|
||||||
except_stmt ::= except
|
except_stmt ::= except
|
||||||
|
except_stmt ::= except_pop_except
|
||||||
|
|
||||||
# Python3 introduced POP_EXCEPT
|
# Python3 introduced POP_EXCEPT
|
||||||
except_suite ::= c_stmts_opt POP_EXCEPT JUMP_FORWARD
|
except_suite ::= c_stmts_opt POP_EXCEPT JUMP_FORWARD
|
||||||
@@ -471,11 +483,12 @@ class Python3Parser(PythonParser):
|
|||||||
except_cond2 ::= DUP_TOP expr COMPARE_OP
|
except_cond2 ::= DUP_TOP expr COMPARE_OP
|
||||||
jmp_false POP_TOP designator POP_TOP
|
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 POP_EXCEPT 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 return_stmts
|
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_ABSOLUTE
|
||||||
jmp_abs ::= JUMP_BACK
|
jmp_abs ::= JUMP_BACK
|
||||||
|
|
||||||
|
@@ -618,7 +618,8 @@ class Scanner27(scan.Scanner):
|
|||||||
for i in self.op_range(0, n):
|
for i in self.op_range(0, n):
|
||||||
op = code[i]
|
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)
|
self.detect_structure(i, op)
|
||||||
|
|
||||||
if op >= HAVE_ARGUMENT:
|
if op >= HAVE_ARGUMENT:
|
||||||
|
@@ -313,7 +313,8 @@ class Scanner3(scan.Scanner):
|
|||||||
for offset in self.op_range(0, codelen):
|
for offset in self.op_range(0, codelen):
|
||||||
op = code[offset]
|
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)
|
self.detect_structure(offset)
|
||||||
|
|
||||||
if op >= op3.HAVE_ARGUMENT:
|
if op >= op3.HAVE_ARGUMENT:
|
||||||
@@ -322,7 +323,7 @@ class Scanner3(scan.Scanner):
|
|||||||
|
|
||||||
if label is None:
|
if label is None:
|
||||||
if op in op3.hasjrel and op != FOR_ITER:
|
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:
|
elif op in op3.hasjabs:
|
||||||
if op in (JUMP_IF_FALSE_OR_POP, JUMP_IF_TRUE_OR_POP):
|
if op in (JUMP_IF_FALSE_OR_POP, JUMP_IF_TRUE_OR_POP):
|
||||||
if oparg > offset:
|
if oparg > offset:
|
||||||
|
@@ -183,49 +183,7 @@ class Scanner34(scan3.Scanner3):
|
|||||||
parent = struct
|
parent = struct
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if op == SETUP_EXCEPT:
|
if op in (POP_JUMP_IF_FALSE, POP_JUMP_IF_TRUE):
|
||||||
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):
|
|
||||||
start = offset + self.op_size(op)
|
start = offset + self.op_size(op)
|
||||||
target = self.get_target(offset)
|
target = self.get_target(offset)
|
||||||
rtarget = self.restrict_to_parent(target, parent)
|
rtarget = self.restrict_to_parent(target, parent)
|
||||||
|
@@ -317,6 +317,8 @@ TABLE_DIRECT = {
|
|||||||
'tryelsestmtl': ( '%|try:\n%+%c%-%c%|else:\n%+%c%-', 1, 3, 4 ),
|
'tryelsestmtl': ( '%|try:\n%+%c%-%c%|else:\n%+%c%-', 1, 3, 4 ),
|
||||||
'tf_trystmt': ( '%c%-%c%+', 1, 3 ),
|
'tf_trystmt': ( '%c%-%c%+', 1, 3 ),
|
||||||
'tf_tryelsestmt': ( '%c%-%c%|else:\n%+%c', 1, 3, 4 ),
|
'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_cond1': ( '%|except %c:\n', 1 ),
|
||||||
'except_cond2': ( '%|except %c as %c:\n', 1, 5 ),
|
'except_cond2': ( '%|except %c as %c:\n', 1, 5 ),
|
||||||
'except_suite': ( '%+%c%-%C', 0, (1, maxint, '') ),
|
'except_suite': ( '%+%c%-%C', 0, (1, maxint, '') ),
|
||||||
@@ -503,12 +505,6 @@ class Walker(GenericASTTraversal, object):
|
|||||||
self.pending_newlines = 0
|
self.pending_newlines = 0
|
||||||
self.hide_internal = True
|
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
|
return
|
||||||
|
|
||||||
f = property(lambda s: s.params['f'],
|
f = property(lambda s: s.params['f'],
|
||||||
@@ -1251,7 +1247,6 @@ class Walker(GenericASTTraversal, object):
|
|||||||
# self.print_("-----")
|
# self.print_("-----")
|
||||||
# self.print(startnode)
|
# self.print(startnode)
|
||||||
|
|
||||||
|
|
||||||
fmt = entry[0]
|
fmt = entry[0]
|
||||||
arg = 1
|
arg = 1
|
||||||
i = 0
|
i = 0
|
||||||
|
Reference in New Issue
Block a user