You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-02 16:44:46 +08:00
3.8 exception handling
This commit is contained in:
BIN
test/bytecode_3.8/04_try_finally.pyc
Normal file
BIN
test/bytecode_3.8/04_try_finally.pyc
Normal file
Binary file not shown.
@@ -29,6 +29,10 @@ class Python38Parser(Python37Parser):
|
||||
stmt ::= forelsestmt38
|
||||
stmt ::= forelselaststmt38
|
||||
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 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
|
||||
whilestmt ::= testexpr l_stmts_opt COME_FROM 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
|
||||
whileelsestmt ::= testexpr l_stmts_opt JUMP_BACK POP_BLOCK
|
||||
whileTruestmt ::= l_stmts_opt JUMP_BACK POP_BLOCK
|
||||
whileelsestmt ::= testexpr l_stmts JUMP_BACK POP_BLOCK
|
||||
whileTruestmt ::= l_stmts JUMP_BACK POP_BLOCK
|
||||
while1stmt ::= l_stmts COME_FROM_LOOP
|
||||
while1stmt ::= l_stmts COME_FROM JUMP_BACK COME_FROM_LOOP
|
||||
while1elsestmt ::= l_stmts JUMP_BACK
|
||||
whileTruestmt ::= l_stmts_opt JUMP_BACK NOP
|
||||
whileTruestmt ::= l_stmts_opt JUMP_BACK POP_BLOCK NOP
|
||||
whileTruestmt ::= l_stmts JUMP_BACK NOP
|
||||
whileTruestmt ::= l_stmts JUMP_BACK POP_BLOCK NOP
|
||||
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
|
||||
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_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):
|
||||
@@ -64,14 +85,23 @@ class Python38Parser(Python37Parser):
|
||||
self.remove_rules("""
|
||||
stmt ::= for
|
||||
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 NOP
|
||||
|
||||
for_block ::= l_stmts_opt COME_FROM_LOOP JUMP_BACK
|
||||
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
|
||||
forelselaststmtl ::= SETUP_LOOP expr for_iter store for_block POP_BLOCK else_suitel
|
||||
try_except ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
|
||||
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)
|
||||
|
||||
|
@@ -872,7 +872,7 @@ class Scanner3(Scanner):
|
||||
if_end = self.get_target(pre_rtarget)
|
||||
|
||||
# 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)):
|
||||
if (if_end > start):
|
||||
return
|
||||
|
@@ -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.
|
||||
# for lhs in 'for forelsestmt forelselaststmt forelselaststmtl'.split():
|
||||
# for lhs in 'for forelsestmt forelselaststmt '
|
||||
# 'forelselaststmtl tryfinally38'.split():
|
||||
# del TABLE_DIRECT[lhs]
|
||||
|
||||
TABLE_DIRECT.update({
|
||||
@@ -962,6 +963,9 @@ def customize_for_version3(self, version):
|
||||
(2, 'store'),
|
||||
(0, 'expr'),
|
||||
(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
|
||||
|
@@ -1815,7 +1815,6 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
# except_cond3 is only in Python <= 2.6
|
||||
n_except_cond3 = n_except_cond2
|
||||
|
||||
|
||||
def template_engine(self, entry, startnode):
|
||||
"""The format template interpetation engine. See the comment at the
|
||||
beginning of this module for the how we interpret format
|
||||
@@ -1862,7 +1861,7 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
if isinstance(index, tuple):
|
||||
assert node[index[0]] == index[1], (
|
||||
"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]
|
||||
assert isinstance(index, int), (
|
||||
|
Reference in New Issue
Block a user