def visitTryExcept(self, node): self.reduce(node.body) self.reduce(node.orelse) len_body = len(node.body) if len_body == 0: node.body.append(Pass(node)) for hndlr in node.handlers: self.reduce(hndlr.body) if len(hndlr.body) == 0: hndlr.body.append(Pass(hndlr)) if len_body == 0: node.handlers = [ _ast.ExceptHandler(type=None, name=None, body=[Pass(node)], lineno=node.lineno, col_offset=node.col_offset) ] return len_body == 0 and len(node.orelse) == 0
def test_issue793(self): import _ast as ast body = ast.Module([ ast.TryExcept([ast.Pass(lineno=2, col_offset=4)], [ast.ExceptHandler(ast.Name('Exception', ast.Load(), lineno=3, col_offset=0), None, [], lineno=4, col_offset=0)], [], lineno=1, col_offset=0) ]) exec compile(body, '<string>', 'exec')
def except_handler(type: _ast.expr, name: str, body: List[_ast.stmt]) -> _ast.ExceptHandler: return _ast.ExceptHandler(type=type, name=name, body=body)
def ExceptHandler(exception_type=None, name=None, body=None): body = FormatAndValidateBody(body) return _ast.ExceptHandler(type=exception_type, name=name, body=body)
def split_handlers(self, handlers_blocks): handlers = [] except_instrs = [] ends = [] while len(handlers_blocks): instr = handlers_blocks.pop(0) except_instrs.append(instr) if (instr.opname == 'COMPARE_OP') and (instr.arg == 'exception match'): jump = handlers_blocks.pop(0) assert jump.opname == 'POP_JUMP_IF_FALSE' next_handler = jump.oparg instr = handlers_blocks.pop(0) except_instrs.append(instr) instr = handlers_blocks.pop(0) except_instrs.append(instr) instr = handlers_blocks.pop(0) except_instrs.append(instr) assert except_instrs[0].opname == 'DUP_TOP' assert except_instrs[-3].opname == 'POP_TOP' assert except_instrs[-1].opname == 'POP_TOP' exec_stmnt = self.decompile_block(except_instrs[1:-4]).stmnt() assert len(exec_stmnt) == 1 exc_type = exec_stmnt[0] if except_instrs[-2].opname == 'STORE_NAME': exc_name = _ast.Name(id=except_instrs[-2].arg, ctx=_ast.Store(), lineno=except_instrs[-2].lineno, col_offset=0) else: assert except_instrs[-2].opname == 'POP_TOP' exc_name = None handler_body = [] while len(handlers_blocks): instr = handlers_blocks.pop(0) if instr.i == next_handler: handlers_blocks.insert(0, instr) break handler_body.append(instr) assert handler_body[-1].opname == 'JUMP_FORWARD' ends.append(handler_body[-1].arg) exc_body = self.decompile_block(handler_body[:-1]).stmnt() if not exc_body: exc_body.append(_ast.Pass(lineno=except_instrs[-2].lineno, col_offset=0)) # is this for python 3? if py3 and exc_name is not None: exc_name = exc_name.id handlers.append(_ast.ExceptHandler(type=exc_type, name=exc_name, body=exc_body, lineno=instr.lineno, col_offset=0)) except_instrs = [] assert except_instrs[-1].opname == 'END_FINALLY' if len(except_instrs) == 1: pass else: 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] ends.append(except_instrs[-2].arg) 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)) handlers.append(_ast.ExceptHandler(type=None, name=None, body=exc_body, lineno=except_instrs[0].lineno, col_offset=0)) assert all(e == ends[0] for e in ends) end = ends[0] return end, handlers