Towards Python3 getting try/except working more often.

This commit is contained in:
rocky
2015-12-30 09:46:52 -05:00
parent 313a8578b3
commit 657eeb7de8
10 changed files with 49 additions and 59 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -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

View File

@@ -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)
#-----

View File

@@ -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

View File

@@ -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:

View File

@@ -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:

View File

@@ -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)

View File

@@ -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