diff --git a/test/bytecode_2.4/02_try_except_finally.pyc b/test/bytecode_2.4/02_try_except_finally.pyc new file mode 100644 index 00000000..f113093f Binary files /dev/null and b/test/bytecode_2.4/02_try_except_finally.pyc differ diff --git a/test/simple_source/bug22/02_try_except_finally.py b/test/simple_source/bug22/02_try_except_finally.py new file mode 100644 index 00000000..ad10deb7 --- /dev/null +++ b/test/simple_source/bug22/02_try_except_finally.py @@ -0,0 +1,17 @@ +# Adapted from Python 2.4 bdb.py runeval() + +# In Python 2.4 and before, try/finally has to be one block +# and try/except has to be in a separate block. + +# In Python 2.5 and later, these can be combined into one "try" block, +# and indeed compiling this in 2.5+ will in fact combine the blocks. +# And that's okay, even if it might not be what was written. + +# However for 2.4 and before make sure this _isn't_ combined into one block. +try: + try: + quitting = eval("1+2") + except RuntimeError: + pass +finally: + quitting = 1 diff --git a/test/stdlib/runtests.sh b/test/stdlib/runtests.sh index 3cb2e1c3..e83cea30 100755 --- a/test/stdlib/runtests.sh +++ b/test/stdlib/runtests.sh @@ -17,7 +17,6 @@ case $PYVERSION in [test_codecs.py]=1 # need to fix tryelse [test_decorators.py]=1 # Syntax error decorators? [test_dis.py]=1 # We change line numbers - duh! - [test_format.py]=1 # Control flow? [test_frozen.py]=1 [test_grp.py]=1 # Long test - might work Control flow? [test_imp.py]=1 # Control flow? diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index abd52a41..0210b951 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -293,6 +293,9 @@ class SourceWalker(GenericASTTraversal, object): TABLE_DIRECT.update({ 'importmultiple': ( '%|import %c%c\n', 2, 3), 'import_cont' : ( ', %c', 2), + 'tryfinallystmt': ( '%|try:\n%+%c%-%|finally:\n%+%c%-', + (1, 'suite_stmts_opt') , + (5, 'suite_stmts_opt') ) }) if version == 2.3: TABLE_DIRECT.update({ @@ -311,9 +314,6 @@ class SourceWalker(GenericASTTraversal, object): ])]) pass if version <= 2.3: - TABLE_DIRECT.update({ - 'tryfinallystmt': ( '%|try:\n%+%c%-%|finally:\n%+%c%-\n\n', 1, 4 ) - }) if version <= 2.1: TABLE_DIRECT.update({ 'importmultiple': ( '%c', 2 ), @@ -339,6 +339,18 @@ class SourceWalker(GenericASTTraversal, object): 'withasstmt': ( '%|with %c as (%c):\n%+%c%-', 0, 2, 3), }) + # In 2.5+ "except" handlers and the "finally" can appear in one + # "try" statement. So the below has the effect of combining the + # "tryfinally" with statement with the "try_except" statement + def tryfinallystmt(node): + if len(node[1][0]) == 1 and node[1][0][0] == 'stmt': + if node[1][0][0][0] == 'try_except': + node[1][0][0][0].kind = 'tf_try_except' + if node[1][0][0][0] == 'tryelsestmt': + node[1][0][0][0].kind = 'tf_tryelsestmt' + self.default(node) + self.n_tryfinallystmt = tryfinallystmt + ######################################## # Python 2.6+ # except as @@ -1029,15 +1041,6 @@ class SourceWalker(GenericASTTraversal, object): n_store_subscr = n_subscript = n_delete_subscr -# 'tryfinallystmt': ( '%|try:\n%+%c%-%|finally:\n%+%c%-', 1, 5 ), - def n_tryfinallystmt(self, node): - if len(node[1][0]) == 1 and node[1][0][0] == 'stmt': - if node[1][0][0][0] == 'try_except': - node[1][0][0][0].kind = 'tf_try_except' - if node[1][0][0][0] == 'tryelsestmt': - node[1][0][0][0].kind = 'tf_tryelsestmt' - self.default(node) - def n_exec_stmt(self, node): """ exec_stmt ::= expr exprlist DUP_TOP EXEC_STMT