def test_Try(self): # except exc_clause = ast.ExceptHandler(ast.Name('X', ast.Load()), None, [ast.Pass()]) exc_clause_2 = ast.ExceptHandler(None, None, [ast.Pass()]) try_except = ast.Try([ast.Pass()], [exc_clause, exc_clause_2], None, None) self.verify(try_except, 'try:pass\nexcept X:pass\nexcept:pass') # except/else try_except_else = ast.Try([ast.Pass()], [exc_clause, exc_clause_2], [ast.Pass()], None) self.verify(try_except_else, 'try:pass\nexcept X:pass\nexcept:pass\nelse:pass') # except/finally exc_clause = ast.ExceptHandler(None, None, [ast.Pass()]) try_except_finally = ast.Try([ast.Pass()], [exc_clause_2], None, [ast.Pass()]) self.verify(try_except_finally, 'try:pass\nexcept:pass\nfinally:pass') # except/else/finally try_except_else_finally = ast.Try([ast.Pass()], [exc_clause_2], [ast.Pass()], [ast.Pass()]) self.verify(try_except_else_finally, 'try:pass\nexcept:pass\nelse:pass\nfinally:pass') # else/finally try_else_finally = ast.Try([ast.Pass()], None, [ast.Pass()], [ast.Pass()]) self.verify(try_else_finally, 'try:pass\nelse:pass\nfinally:pass') # finally try_finally = ast.Try([ast.Pass()], None, None, [ast.Pass()]) self.verify(try_finally, 'try:pass\nfinally:pass')
def python_ast(self): te = ast.TryExcept(lineno=self.line, col_offset=self.column) te.handlers = [] te.body = self.try_sequence.python_ast() for k, v in self.catches.items(): if k == "#default#": eh = ast.ExceptHandler(lineno=self.line, col_offset=self.column) eh.type = None eh.name = None eh.body = v.python_ast() te.handlers.append(eh) else: eh = ast.ExceptHandler(lineno=self.line, col_offset=self.column) eh.type = ast.Name(k, ast.Load(), lineno=self.line, col_offset=self.column) eh.name = None eh.body = v.python_ast() te.handlers.append(eh) te.orelse = [] return te
def __init__(self, ignore_exceptions=(), catch_exception=None): raise_cmd = ast.Raise() if sys.version_info > (3, 0): start_debug_cmd = ast.Expr(value=ast.Call( ast.Name("start_debugging", ast.Load()), [], [], )) else: start_debug_cmd = ast.Expr(value=ast.Call( ast.Name("start_debugging", ast.Load()), [], [], None, None)) catch_exception_node = None if catch_exception is not None: catch_exception_node = ast.Name(catch_exception.__name__, ast.Load()) self.exception_handlers = [ ast.ExceptHandler(type=catch_exception_node, name=None, body=[start_debug_cmd]) ] for exception_class in ignore_exceptions: ignore_exception_node = ast.Name(exception_class.__name__, ast.Load()) self.exception_handlers.insert( 0, ast.ExceptHandler(type=ignore_exception_node, name=None, body=[raise_cmd]))
def testWriteExceptDispatcherBareExceptionNotLast(self): visitor = stmt.StatementVisitor(_MakeModuleBlock()) handlers = [ast.ExceptHandler(type=None), ast.ExceptHandler(type=ast.Name(id='foo'))] self.assertRaisesRegexp(util.ParseError, r"default 'except:' must be last", visitor._write_except_dispatcher, # pylint: disable=protected-access 'exc', 'tb', handlers)
def generic_visit(self, node): import ast import sys ast.NodeTransformer.generic_visit(self, node) if isinstance(node, ast.stmt) and not isinstance(node, ast.FunctionDef): if sys.version_info[0] == 3: new_node = ast.Try(body=[node], handlers=[ ast.ExceptHandler(type=None, name=None, body=[ast.Pass()]) ], orelse=[], finalbody=[ast.Pass()]) else: new_node = ast.TryExcept(body=[node], handlers=[ ast.ExceptHandler( type=None, name=None, body=[ast.Pass()]) ], orelse=[]) return ast.copy_location(new_node, node) return node
def test_Try(self): # try/except where 'except' is only dead code. exc_clause = ast.ExceptHandler(None, None, [ast.Expr(ast.Str('dead code'))]) try_exc = ast.Try([ast.Pass()], [exc_clause], [], []) expect = ast.Try([ast.Pass()], [ast.ExceptHandler(None, None, [ast.Pass()])], [], []) self.check_transform(try_exc, expect)
def testWriteExceptDispatcherBareExcept(self): visitor = stmt.StatementVisitor(_MakeModuleBlock()) handlers = [ast.ExceptHandler(type=ast.Name(id='foo')), ast.ExceptHandler(type=None)] self.assertEqual(visitor._write_except_dispatcher( # pylint: disable=protected-access 'exc', 'tb', handlers), [1, 2]) expected = re.compile(r'ResolveGlobal\(.*foo.*\bIsInstance\(.*' r'goto Label1.*goto Label2', re.DOTALL) self.assertRegexpMatches(visitor.writer.out.getvalue(), expected)
def visitException_handler(self, ctx: PlSqlParser.Exception_handlerContext): ret = self.visitChildren(ctx) ret = deque(ret) exception = ret.popleft() body = list(ret) return ast.ExceptHandler(type=exception, body=body, name=None)
def visit_TryFinally(self, node): node.body.extend(node.finalbody) node.finalbody.append(ast.Raise(None, None, None)) self.update = True return ast.TryExcept(node.body, [ast.ExceptHandler(None, None, node.finalbody)], [])
def visit_Assign(self, node: ast.Assign) -> Any: self.generic_visit(node) target = node.targets[0] if not isinstance(target, ast.Name): return node expr = ast.Name(id=target.id, ctx=ast.Load()) name = target.id check = ast.Try( body=[ast.Expr(expr)], handlers=[ ast.ExceptHandler( type=ast.Tuple( elts=[ast.Name(id=_n(NameError), ctx=ast.Load())], ctx=ast.Load(), ), name=None, body=[ast.Expr(value=ast.Constant(value=Ellipsis))], ) ], orelse=[ ast.Raise( exc=ast.Call( func=ast.Name( id=_n(ImmutabilityGuard.proxy_Assign), ctx=ast.Load() ), args=[ast.Constant(value=name)], keywords=[], ), cause=None, ) ], finalbody=[], ) return [check, node]
def get_import_code(self, node, fname='<string>'): """Get compiled code of all top-level import statements found in the AST of node.""" self._import_nodes = [] self.visit(node) body = [] for imp_node in self._import_nodes: if isinstance(imp_node, ast.ImportFrom) and \ imp_node.module == '__future__': # 'SyntaxError: from __future__ imports must occur at the # beginning of the file' is raised if a 'from __future__ import' # is wrapped in try-except, so use only the import statement. body.append(imp_node) else: body.append( ast.TryExcept(body=[imp_node], handlers=[ ast.ExceptHandler(type=None, name=None, body=[ast.Pass()]) ], orelse=[])) node = ast.Module(body=body) ast.fix_missing_locations(node) code = compile(node, fname, 'exec') return code
def 例外处理(类型, 名称, 主体, 片段): return ast.ExceptHandler( type=类型, name=名称, body=主体, lineno=语法树.取行号(片段), col_offset=语法树.取列号(片段))
def test_ExceptHandler(self): except_ = ast.ExceptHandler(None, None, [ast.Pass()]) self.verify(except_, 'except:pass') except_.type = ast.Name('Exception', ast.Load()) self.verify(except_, 'except Exception:pass') except_.name = ast.Name('exc', ast.Store()) self.verify(except_, 'except Exception as exc:pass')
def visit_FunctionDef(self, node): if len(preconditions[node.name]) == 0: return node ast_name = ast.Name(id="PreconditionException", ctx=ast.Load()) node_exception = ast.Raise(exc=ast_name, cause=None) precondition_node = preconditions[node.name][0] assert_node = ast.Assert(precondition_node, lineno=node.lineno, col_offset=node.col_offset, end_lineno=node.lineno, end_col_offset=node.end_col_offset) ast_exception = ast.Name(id="Exception", ctx=ast.Load()) handler = ast.ExceptHandler(type=ast_exception, name=None, body=[node_exception]) try_node = ast.Try(body=[assert_node], handlers=[handler], orelse=[], finalbody=[node.body]) #if_node = ast.If(precondition_node,[node.body],[node_exception]) node_res = ast.FunctionDef(node.name, node.args, [try_node], node.decorator_list, node.returns, node.type_comment, lineno=node.lineno, col_offset=node.col_offset, end_lineno=node.lineno, end_col_offset=node.end_col_offset) ast.fix_missing_locations(node_res) return node_res
def visit_ExceptHandler(self, node): if node.name: new_node = ast.ExceptHandler(self._visit(node.type), node.name.id, self._visit(node.body)) return ast.copy_location(new_node, node) else: return self.generic_visit(node)
def assemble(self): try_ = self.parent.assemble() handler = ast.ExceptHandler(type=self.parent.type, name=self.parent.name, body=self.body) try_.handlers.append(handler) return try_
def ast_nodes(self) -> List[ast.stmt]: """Get the list of generated AST nodes. In case the `wrap_nodes` property was set, the nodes will be wrapped in ``` try: [nodes] except BaseException: pass ``` Returns: A list of AST nodes """ if self._wrap_nodes: nodes: List[ast.stmt] = [ ast.Try( body=self._ast_nodes, handlers=[ ast.ExceptHandler( body=[ast.Pass()], name=None, type=ast.Name(ctx=ast.Load(), id="BaseException"), ) ], orelse=[], finalbody=[], ) ] return nodes return self._ast_nodes
def visit_For(self, loop_): """ >>> self = FirstPassFor(buffer='foo') >>> code = ''' ... ... for i in range(5): ... for j in range(5): ... k = i + j ... print(k) ... ... ''' >>> tree = ast.parse(code) >>> loop_, = tree.body """ loop = self.generic_visit(loop_) var = ast.Name(id=__random_string__(), ctx=ast.Store()) assign = ast.Assign(targets=[var], value=ast.Call(func=ast.Name(id='iter', ctx=ast.Load()), args=[loop.iter], keywords=[])) first_pass = ast.Try( body=[ast.Assign(targets=[loop.target], value=ast.Call(func=ast.Name(id='next', ctx=ast.Load()), args=[ast.Name(id=var, ctx=ast.Load())], keywords=[]))], handlers=[ast.ExceptHandler(type=ast.Name(id='StopIteration', ctx=ast.Load()), name=None, body=[ast.Pass()])], orelse=loop.body, finalbody=[] ) content = f'`for {astor.to_source(loop.target).strip()} in {astor.to_source(loop.iter).strip()} ...`' return [ make_annotation(buffer=self.buffer, content=content, cell_type='2', lineno=loop.lineno), ast.Expr(loop.iter), assign, first_pass ]
def mutate(self, node, _): """Modify the exception handler with another exception type.""" except_id = CosmicRayTestingException.__name__ except_type = ast.Name(id=except_id, ctx=ast.Load()) new_node = ast.ExceptHandler(type=except_type, name=node.name, body=node.body) return new_node
def visit_ExceptHandler(self, node): if node.type is None: return ast.copy_location(ast.ExceptHandler( type=ast.Name(id='BaseException', ctx=ast.Load()), name=node.name, body=node.body ), node) return self.generic_visit(node)
def visit_TryExcept(self, node): if node.orelse: node.body.append( ast.TryExcept(node.orelse, [ast.ExceptHandler(None, None, [ast.Pass()])], [])) node.orelse = [] return node
def replace_unsafe_value(node, replace_self=None): """Modify value from assignment if unsafe. If replace_self is given, only assignments starting with 'self.' are processed, the assignment node is returned with 'self.' replaced by the value of replace_self (typically the class name). For other assignments, None is returned.""" for i, target in enumerate(node.targets): if not isinstance(target, (ast.Name, ast.Attribute)): # Only process assignments to names and attributes, # not tuples. return None if replace_self: if isinstance(target, ast.Attribute) and \ isinstance(target.value, ast.Name) and \ target.value.id == 'self' and \ isinstance(target.value.ctx, ast.Load): node.targets[i].value.id = replace_self if target.attr == '__name__': node.value = ast.copy_location(ast.Str(s=''), node.value) elif target.attr in ('__dict__', '__class__', '__bases__', '__doc__'): return None else: return None elif isinstance(target, ast.Name) and \ isinstance(target.ctx, ast.Store): if target.id == '__metaclass__': # Do not modify __metaclass__ assignments return node elif target.id == '__slots__': node.value = ast.copy_location( ast.List(elts=[], ctx=ast.Load()), node.value) if isinstance(node.value, (ast.Str, ast.Num)): pass elif isinstance(node.value, (ast.List, ast.Tuple)): node.value.elts = [] elif isinstance(node.value, ast.Dict): node.value.keys = [] node.value.values = [] elif isinstance(node.value, ast.ListComp): node.value = ast.copy_location(ast.List(elts=[], ctx=ast.Load()), node.value) elif isinstance(node.value, ast.Call): type_node = _PyCompleteDocument.CodeRemover._get_type_node_for_function_node(node.value.func) if type_node: # Wrap class lookup in try-except because it is not fail-safe. node.value = ast.copy_location(type_node, node.value) node = ast.copy_location(ast.TryExcept(body=[node], handlers=[ ast.ExceptHandler(type=None, name=None, body=[ast.Pass()])], orelse=[]), node) ast.fix_missing_locations(node) else: node.value = ast.copy_location( ast.Name(id='None', ctx=ast.Load()), node.value) else: node.value = ast.copy_location(ast.Name(id='None', ctx=ast.Load()), node.value) return node
def make_exception_handler(): """excepthandler = ExceptHandler(expr? type, identifier? name, stmt* body)""" # The ast module has it capitalized for some reason return ast.ExceptHandler( type=ast.Name("Exception", ctx=ast.Load()), name="e", body=[ast.Pass()], )
def add_required_imports(tree: ast.Module, required_imports: typ.Set[common.ImportDecl]) -> None: """Add imports required by fixers. Some fixers depend on modules which may not be imported in the source module. As an example, occurrences of 'map' might be replaced with 'itertools.imap', in which case, "import itertools" will be added in the module scope. A further quirk is that all reqired imports must be added before any other statment. This is because that statement could be subject to the fix which requires the import. As a side effect, a module may end up being imported twice, if the module is imported after some statement. """ (future_imports_offset, imports_end_offset, found_imports) = parse_imports(tree) missing_imports = sorted(required_imports - found_imports) import_node: ast.stmt for import_decl in missing_imports: if import_decl.import_name is None: import_node = ast.Import( names=[ast.alias(name=import_decl.module_name, asname=None)]) else: import_node = ast.ImportFrom( module=import_decl.module_name, level=0, names=[ast.alias(name=import_decl.import_name, asname=None)], ) if import_decl.py2_module_name: asname = import_decl.import_name or import_decl.module_name fallback_import = ast.Import(names=[ ast.alias(name=import_decl.py2_module_name, asname=asname) ]) import_node = ast.Try( body=[import_node], handlers=[ ast.ExceptHandler( type=ast.Name(id='ImportError', ctx=ast.Load()), name=None, body=[fallback_import], ) ], orelse=[], finalbody=[], ) if import_decl.module_name == '__future__': tree.body.insert(future_imports_offset, import_node) future_imports_offset += 1 imports_end_offset += 1 else: tree.body.insert(imports_end_offset, import_node) imports_end_offset += 1
def __call__(self, target, engine): remaining = self.expression assignments = [] while remaining: if self.ignore_prefix and match_prefix(remaining) is not None: compiler = engine.parse(remaining) assignment = compiler.assign_value(target) remaining = "" else: for m in split_parts.finditer(remaining): expression = remaining[:m.start()] remaining = remaining[m.end():] break else: expression = remaining remaining = "" expression = expression.replace('\\|', '|') assignment = self.translate_proxy(engine, expression, target) assignments.append(assignment) if not assignments: if not remaining: raise ExpressionError("No input:", remaining) assignments.append(self.translate_proxy(engine, remaining, target)) for i, assignment in enumerate(reversed(assignments)): if i == 0: body = assignment else: body = [ TryExcept( body=assignment, handlers=[ ast.ExceptHandler( type=ast.Tuple(elts=map( resolve_global, self.exceptions), ctx=ast.Load()), name=None, body=body if exc_clear is None else body + [ ast.Expr( ast.Call( func=load("__exc_clear"), args=[], keywords=[], starargs=None, kwargs=None, )) ], ) ], ) ] return body
def gen_block_TryExcept(self, expr_try, expr_except): assert ((type(expr_try) and type(expr_except)) == list) # TODO: could be made in one-liner exception_handler = [ ast.ExceptHandler(ast.Name("Exception", ast.Store()), "e", expr_except) ] tryExcept_block = ast.Try(expr_try, exception_handler, [], []) return (tryExcept_block)
def test_try(self): p = ast.Pass() t = ast.Try([], [], [], [p]) self.stmt(t, "empty body on Try") t = ast.Try([ast.Expr(ast.Name("x", ast.Store()))], [], [], [p]) self.stmt(t, "must have Load context") t = ast.Try([p], [], [], []) self.stmt(t, "Try has neither except handlers nor finalbody") t = ast.Try([p], [], [p], [p]) self.stmt(t, "Try has orelse but no except handlers") t = ast.Try([p], [ast.ExceptHandler(None, "x", [])], [], []) self.stmt(t, "empty body on ExceptHandler") e = [ast.ExceptHandler(ast.Name("x", ast.Store()), "y", [p])] self.stmt(ast.Try([p], e, [], []), "must have Load context") e = [ast.ExceptHandler(None, "x", [p])] t = ast.Try([p], e, [ast.Expr(ast.Name("x", ast.Store()))], [p]) self.stmt(t, "must have Load context") t = ast.Try([p], e, [p], [ast.Expr(ast.Name("x", ast.Store()))]) self.stmt(t, "must have Load context")
def wrap_with_try(self, node): """Wrap an ast node in a 'try' node to enter debug on exception.""" handlers = [] if self.ignore_exceptions is None: handlers.append(ast.ExceptHandler(type=None, name=None, body=[ast.Raise()])) else: ignores_nodes = self.ignore_exceptions handlers.append(ast.ExceptHandler(type=ast.Tuple(ignores_nodes, ast.Load()), name=None, body=[ast.Raise()])) if self.catch_exception is None or \ get_node_value(self.catch_exception) not in \ (get_node_value(ast_node) for ast_node in self.ignore_exceptions): call_extra_parameters = [] if IS_PYTHON_3 else [None, None] start_debug_cmd = ast.Expr( value=ast.Call(ast.Name("start_debugging", ast.Load()), [], [], *call_extra_parameters)) catch_exception_type = None if self.catch_exception is not None: catch_exception_type = self.catch_exception handlers.append(ast.ExceptHandler(type=catch_exception_type, name=None, body=[start_debug_cmd])) try_except_extra_params = {"finalbody": []} if IS_PYTHON_3 else {} new_node = self.ast_try_except(orelse=[], body=[node], handlers=handlers, **try_except_extra_params) return ast.copy_location(new_node, node)
def visit_Try(self, try_): handlers = [] for handler in try_.handlers: handlers.append( ast.ExceptHandler(type=handler.type, name=None, body=self._annotate_nodes(handler.body))) return ast.Try(body=self._annotate_nodes(try_.body), handlers=handlers, orelse=self._annotate_nodes(try_.orelse), finalbody=self._annotate_nodes(try_.finalbody))
def _try_fallback(node: ast.stmt, fallback_node: ast.stmt) -> ast.Try: return ast.Try( body=[node], handlers=[ ast.ExceptHandler(type=ast.Name(id="ImportError", ctx=ast.Load()), name=None, body=[fallback_node]) ], orelse=[], finalbody=[], )