From 64bbac4d9af2486f85cd6d0fa8115e50d03912d8 Mon Sep 17 00:00:00 2001 From: kichik Date: Tue, 15 Oct 2013 19:33:08 +0200 Subject: [PATCH] Fix `return` in `except` The following code tries to return a value from an `except` block but fails with an assertion. ```python import meta def f(x): try: return x except: return x + 1 # <== offender f_ast = meta.decompiler.decompile_func(f) meta.asttools.print_ast(f_ast) print meta.dump_python_source(f_ast) ``` It results in the following assertion: ```python AssertionError: 21 RETURN_VALUE ``` The suggested patch simply adds support for `return` and seems to work. It results in valid AST. --- meta/decompiler/control_flow_instructions.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/meta/decompiler/control_flow_instructions.py b/meta/decompiler/control_flow_instructions.py index c8777db..72e1c11 100644 --- a/meta/decompiler/control_flow_instructions.py +++ b/meta/decompiler/control_flow_instructions.py @@ -228,9 +228,12 @@ def split_handlers(self, handlers_blocks): assert except_instrs[0].opname == 'POP_TOP' assert except_instrs[1].opname == 'POP_TOP' assert except_instrs[2].opname == 'POP_TOP' - assert except_instrs[-2].opname in ['JUMP_FORWARD', 'JUMP_ABSOLUTE'], except_instrs[-2] + assert except_instrs[-2].opname in ['JUMP_FORWARD', 'JUMP_ABSOLUTE', 'RETURN_VALUE'], except_instrs[-2] ends.append(except_instrs[-2].arg) - exc_body = self.decompile_block(except_instrs[3:-2]).stmnt() + if except_instrs[-2].opname == 'RETURN_VALUE': + exc_body = self.decompile_block(except_instrs[3:-1]).stmnt() + else: + exc_body = self.decompile_block(except_instrs[3:-2]).stmnt() if not exc_body: exc_body.append(_ast.Pass(lineno=except_instrs[-2].lineno, col_offset=0))