3.8 exception handling

This commit is contained in:
rocky
2019-04-11 12:09:24 -04:00
parent 94eff282f8
commit 5e1340a2fc
5 changed files with 42 additions and 9 deletions

Binary file not shown.

View File

@@ -29,6 +29,10 @@ class Python38Parser(Python37Parser):
stmt ::= forelsestmt38 stmt ::= forelsestmt38
stmt ::= forelselaststmt38 stmt ::= forelselaststmt38
stmt ::= forelselaststmtl38 stmt ::= forelselaststmtl38
stmt ::= tryfinally38
# FIXME this should be restricted to being inside a try block
stmt ::= except_ret38
for38 ::= expr get_iter store for_block JUMP_BACK for38 ::= expr get_iter store for_block JUMP_BACK
for38 ::= expr for_iter store for_block JUMP_BACK for38 ::= expr for_iter store for_block JUMP_BACK
@@ -39,21 +43,38 @@ class Python38Parser(Python37Parser):
forelselaststmtl38 ::= expr for_iter store for_block POP_BLOCK else_suitel forelselaststmtl38 ::= expr for_iter store for_block POP_BLOCK else_suitel
whilestmt ::= testexpr l_stmts_opt COME_FROM JUMP_BACK POP_BLOCK whilestmt ::= testexpr l_stmts_opt COME_FROM JUMP_BACK POP_BLOCK
whilestmt ::= testexpr l_stmts_opt JUMP_BACK POP_BLOCK whilestmt ::= testexpr l_stmts_opt JUMP_BACK POP_BLOCK
whilestmt ::= testexpr returns POP_BLOCK whilestmt ::= testexpr returns POP_BLOCK
while1elsestmt ::= l_stmts JUMP_BACK while1elsestmt ::= l_stmts JUMP_BACK
whileelsestmt ::= testexpr l_stmts_opt JUMP_BACK POP_BLOCK whileelsestmt ::= testexpr l_stmts JUMP_BACK POP_BLOCK
whileTruestmt ::= l_stmts_opt JUMP_BACK POP_BLOCK whileTruestmt ::= l_stmts JUMP_BACK POP_BLOCK
while1stmt ::= l_stmts COME_FROM_LOOP while1stmt ::= l_stmts COME_FROM_LOOP
while1stmt ::= l_stmts COME_FROM JUMP_BACK COME_FROM_LOOP while1stmt ::= l_stmts COME_FROM JUMP_BACK COME_FROM_LOOP
while1elsestmt ::= l_stmts JUMP_BACK while1elsestmt ::= l_stmts JUMP_BACK
whileTruestmt ::= l_stmts_opt JUMP_BACK NOP whileTruestmt ::= l_stmts JUMP_BACK NOP
whileTruestmt ::= l_stmts_opt JUMP_BACK POP_BLOCK NOP whileTruestmt ::= l_stmts JUMP_BACK POP_BLOCK NOP
for_block ::= l_stmts_opt _come_from_loops JUMP_BACK for_block ::= l_stmts_opt _come_from_loops JUMP_BACK
except_cond1 ::= DUP_TOP expr COMPARE_OP jmp_false
POP_TOP POP_TOP POP_TOP
POP_EXCEPT
try_except ::= SETUP_FINALLY suite_stmts_opt POP_BLOCK try_except ::= SETUP_FINALLY suite_stmts_opt POP_BLOCK
except_handler38 except_handler38
except_ret38 ::= SETUP_FINALLY expr ROT_FOUR POP_BLOCK POP_EXCEPT
CALL_FINALLY RETURN_VALUE COME_FROM_FINALLY
suite_stmts_opt END_FINALLY
except_handler38 ::= JUMP_FORWARD COME_FROM_FINALLY except_handler38 ::= JUMP_FORWARD COME_FROM_FINALLY
except_stmts END_FINALLY opt_come_from_except except_stmts END_FINALLY opt_come_from_except
tryfinallystmt ::= SETUP_FINALLY suite_stmts_opt POP_BLOCK
BEGIN_FINALLY COME_FROM_FINALLY suite_stmts_opt
END_FINALLY
tryfinally38 ::= SETUP_FINALLY POP_BLOCK CALL_FINALLY
returns
COME_FROM_FINALLY END_FINALLY suite_stmts
tryfinally38 ::= SETUP_FINALLY POP_BLOCK CALL_FINALLY
returns
COME_FROM_FINALLY POP_FINALLY returns
END_FINALLY
""" """
def __init__(self, debug_parser=PARSER_DEFAULT_DEBUG): def __init__(self, debug_parser=PARSER_DEFAULT_DEBUG):
@@ -64,14 +85,23 @@ class Python38Parser(Python37Parser):
self.remove_rules(""" self.remove_rules("""
stmt ::= for stmt ::= for
stmt ::= forelsestmt stmt ::= forelsestmt
stmt ::= try_except36
for ::= SETUP_LOOP expr for_iter store for_block POP_BLOCK for ::= SETUP_LOOP expr for_iter store for_block POP_BLOCK
for ::= SETUP_LOOP expr for_iter store for_block POP_BLOCK NOP for ::= SETUP_LOOP expr for_iter store for_block POP_BLOCK NOP
for_block ::= l_stmts_opt COME_FROM_LOOP JUMP_BACK for_block ::= l_stmts_opt COME_FROM_LOOP JUMP_BACK
forelsestmt ::= SETUP_LOOP expr for_iter store for_block POP_BLOCK else_suite forelsestmt ::= SETUP_LOOP expr for_iter store for_block POP_BLOCK else_suite
forelselaststmt ::= SETUP_LOOP expr for_iter store for_block POP_BLOCK else_suitec forelselaststmt ::= SETUP_LOOP expr for_iter store for_block POP_BLOCK else_suitec
forelselaststmtl ::= SETUP_LOOP expr for_iter store for_block POP_BLOCK else_suitel forelselaststmtl ::= SETUP_LOOP expr for_iter store for_block POP_BLOCK else_suitel
try_except ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK try_except ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
except_handler opt_come_from_except except_handler opt_come_from_except
tryfinallystmt ::= SETUP_FINALLY suite_stmts_opt POP_BLOCK
LOAD_CONST COME_FROM_FINALLY suite_stmts_opt
END_FINALLY
tryfinally36 ::= SETUP_FINALLY returns
COME_FROM_FINALLY suite_stmts_opt END_FINALLY
""") """)
super(Python37Parser, self).customize_grammar_rules(tokens, customize) super(Python37Parser, self).customize_grammar_rules(tokens, customize)

View File

@@ -872,7 +872,7 @@ class Scanner3(Scanner):
if_end = self.get_target(pre_rtarget) if_end = self.get_target(pre_rtarget)
# If the jump target is back, we are looping # If the jump target is back, we are looping
if (if_end < pre_rtarget and if (if_end < pre_rtarget and self.version < 3.8 and
(code[prev_op[if_end]] == self.opc.SETUP_LOOP)): (code[prev_op[if_end]] == self.opc.SETUP_LOOP)):
if (if_end > start): if (if_end > start):
return return

View File

@@ -938,7 +938,8 @@ def customize_for_version3(self, version):
####################### #######################
# FIXME: pytest doesn't add proper keys in testing. Reinstate after we have fixed pytest. # FIXME: pytest doesn't add proper keys in testing. Reinstate after we have fixed pytest.
# for lhs in 'for forelsestmt forelselaststmt forelselaststmtl'.split(): # for lhs in 'for forelsestmt forelselaststmt '
# 'forelselaststmtl tryfinally38'.split():
# del TABLE_DIRECT[lhs] # del TABLE_DIRECT[lhs]
TABLE_DIRECT.update({ TABLE_DIRECT.update({
@@ -962,6 +963,9 @@ def customize_for_version3(self, version):
(2, 'store'), (2, 'store'),
(0, 'expr'), (0, 'expr'),
(3, 'for_block'), -2 ), (3, 'for_block'), -2 ),
'tryfinally38': ( '%|try:\n%+%c%-%|finally:\n%+%c%-\n\n',
(3, 'returns'), 6 ),
'except_ret38': ( '%|return %c\n', (1, 'expr') ),
}) })
pass pass
pass pass

View File

@@ -1815,7 +1815,6 @@ class SourceWalker(GenericASTTraversal, object):
# except_cond3 is only in Python <= 2.6 # except_cond3 is only in Python <= 2.6
n_except_cond3 = n_except_cond2 n_except_cond3 = n_except_cond2
def template_engine(self, entry, startnode): def template_engine(self, entry, startnode):
"""The format template interpetation engine. See the comment at the """The format template interpetation engine. See the comment at the
beginning of this module for the how we interpret format beginning of this module for the how we interpret format
@@ -1862,7 +1861,7 @@ class SourceWalker(GenericASTTraversal, object):
if isinstance(index, tuple): if isinstance(index, tuple):
assert node[index[0]] == index[1], ( assert node[index[0]] == index[1], (
"at %s[%d], expected %s node; got %s" % ( "at %s[%d], expected %s node; got %s" % (
node.kind, arg, node[index[0]].kind, index[1]) node.kind, arg, index[1], node[index[0]].kind)
) )
index = index[0] index = index[0]
assert isinstance(index, int), ( assert isinstance(index, int), (