我们从Python开源项目中,提取了以下50个代码示例,用于说明如何使用ast.copy_location()。
def filterstr_to_filterfunc(filter_str: str, logged_in: bool) -> Callable[['Post'], bool]: """Takes an --only-if=... filter specification and makes a filter_func Callable out of it.""" # The filter_str is parsed, then all names occurring in its AST are replaced by loads to post.<name>. A # function Post->bool is returned which evaluates the filter with the post as 'post' in its namespace. class TransformFilterAst(ast.NodeTransformer): def visit_Name(self, node: ast.Name): # pylint:disable=invalid-name,no-self-use if not isinstance(node.ctx, ast.Load): raise InvalidArgumentException("Invalid filter: Modifying variables ({}) not allowed.".format(node.id)) if not hasattr(Post, node.id): raise InvalidArgumentException("Invalid filter: Name {} is not defined.".format(node.id)) if node.id in Post.LOGIN_REQUIRING_PROPERTIES and not logged_in: raise InvalidArgumentException("Invalid filter: Name {} requires being logged in.".format(node.id)) new_node = ast.Attribute(ast.copy_location(ast.Name('post', ast.Load()), node), node.id, ast.copy_location(ast.Load(), node)) return ast.copy_location(new_node, node) input_filename = '<--only-if parameter>' compiled_filter = compile(TransformFilterAst().visit(ast.parse(filter_str, filename=input_filename, mode='eval')), filename=input_filename, mode='eval') def filterfunc(post: 'Post') -> bool: # pylint:disable=eval-used return bool(eval(compiled_filter, {'post': post})) return filterfunc
def visit_BinOp(self, node): node = self.generic_visit(node) left = node.left right = node.right if all(isinstance(value, ast.Num) for value in (left, right)): if isinstance(node.op, tuple(self._operators.keys())): val = self._operators[type(node.op)](left.n, right.n) node = ast.copy_location(ast.Num(n = val), node) return node elif all(isinstance(value, ast.Str) for value in (left, right)): if isinstance(node.op, ast.Add): val = left.s + right.s node = ast.copy_location(ast.Str(s = val), node) return node return self.fold(node) #def visit_GeneratorExp(self, node): # return self.comprehension(node)
def visit_BinOp(self, node: ast.BinOp) -> ast.BinOp: node = self.generic_visit(node) if self._is_numeric_mult(node): if isinstance(node.right, ast.Num): if node.right.n == 0: node = ast.copy_location(ast.Num(n = 0), node) elif node.right.n == 1: node = node.left elif node.right.n == 2: node.op = ast.copy_location(ast.Add(), node.op) node.right = copy(node.left) elif isinstance(node.left , ast.Num): if node.left.n == 0: node = ast.copy_location(ast.Num(n = 0), node) elif node.left.n == 1: node = node.right elif node.left.n == 2: node.op = ast.copy_location(ast.Add(), node.op) node.left = copy(node.right) return node
def stateful_get_all_emojis(self, expr): if not isinstance(expr.value, ast.Await): return expr if not isinstance(expr.value.value, ast.Call): return expr call = expr.value.value if isinstance(call.func, ast.Attribute): if call.func.attr == 'get_all_emojis': if self.interactive and not prompt_change( 'A possible change was found to make get_all_emojis stateful.' ): return expr new_expr = ast.Expr() new_expr.value = ast.Attribute() new_expr.value.value = call.func.value new_expr.value.attr = 'emojis' new_expr.value.ctx = ast.Load() new_expr = ast.copy_location(new_expr, expr) stats_counter['expr_changes'] += 1 return new_expr return expr
def subs(root, **kwargs): '''Substitute ast.Name nodes for numbers in root using the mapping in kwargs. Returns a new copy of root. ''' root = copy.deepcopy(root) class Transformer(ast.NodeTransformer): def visit_FunctionDef(self, node): return node def visit_Name(self, node): if node.id in kwargs and not isinstance(node.ctx, ast.Store): replacement = kwargs[node.id] if isinstance(replacement, int): return ast.copy_location(ast.Num(n=replacement), node) else: return copy.copy(replacement) else: return node return Transformer().visit(root)
def translate_Call_constructor(self, ctx, e): args, keywords = e.args, e.keywords idx = self.idx elt_translation = [] idx_mapping = [] for i, arg in enumerate(args): elt_translation.append(ctx.translate(arg)) n = _util.odict_idx_of(idx, i) idx_mapping.append(n) for keyword in keywords: label = keyword.arg value = keyword.value elt_translation.append(ctx.translate(value)) n = _util.odict_idx_of(idx, label) idx_mapping.append(n) arg_translation = ast.Tuple(elts=elt_translation) return ast.copy_location(_labeled_translation(idx_mapping, arg_translation), e)
def translate_Tuple(self, ctx, e): elts = e.elts rl, im = elts[0], elts[1] rl_trans = ctx.translate(rl) if isinstance(im, ast.Num): n = im.n if isinstance(n, complex): n = n.imag im_trans = ast.copy_location( ast.Num(n), im) else: im_trans = ctx.translate(im) # __builtin__.complex([[rl_trans]], [[im_trans]]) return ast.copy_location( astx.builtin_call('complex', [rl_trans, im_trans]), e)
def propagating(maker): result = lambda node_fn, *node_fns: lambda ctx: next(ast.copy_location(maker(node, *[n(ctx) for n in node_fns]), node) for node in [node_fn(ctx)]) result.__name__ = maker.__name__ return result
def make_module(*stmts): m = ast.Module(list(stmts)) return ast.copy_location(m, stmts[0]) if stmts else m
def maybe_assignment(*expr_fns): if len(expr_fns) == 1: node0 = expr_fns[0](ast.Load()) stmt = ast.Expr(node0) else: lhses = [fn(ast.Store()) for fn in expr_fns[:-1]] node0 = lhses[0] stmt = ast.Assign(lhses, expr_fns[-1](ast.Load())) return ast.copy_location(stmt, node0)
def rewriter(rewrite): def visit(self, t): return ast.copy_location(rewrite(self, self.generic_visit(t)), t) return visit
def visit_Assert(self, t): t = self.generic_visit(t) result = ast.If(t.test, [], [ast.Raise(Call(ast.Name('AssertionError', load), [] if t.msg is None else [t.msg]), None)]) return ast.copy_location(result, t)
def visit_FunctionDef(self, t): t = self.generic_visit(t) fn = Function(t.name, t.args, t.body) for d in reversed(t.decorator_list): fn = Call(d, [fn]) result = ast.Assign([ast.Name(t.name, store)], fn) return ast.copy_location(result, t)
def visit_ListComp(self, t): t = self.generic_visit(t) add_element = ast.Attribute(ast.Name('.elements', load), 'append', load) body = ast.Expr(Call(add_element, [t.elt])) for loop in reversed(t.generators): for test in reversed(loop.ifs): body = ast.If(test, [body], []) body = ast.For(loop.target, loop.iter, [body], []) fn = [body, ast.Return(ast.Name('.elements', load))] args = ast.arguments([ast.arg('.elements', None)], None, [], None, [], []) result = Call(Function('<listcomp>', args, fn), [ast.List([], load)]) return ast.copy_location(result, t)
def visit_Lambda(self, t): t = self.generic_visit(t) result = Function('<lambda>', t.args, [ast.Return(t.body)]) return ast.copy_location(result, t)
def visit_Attribute(self, node): """Flatten one level of attribute access.""" new_node = ast.Name("%s.%s" % (node.value.id, node.attr), node.ctx) return ast.copy_location(new_node, node)
def ast_to_module(node: ast.AST, old_module: types.ModuleType = None, file: str = None) -> types.ModuleType: """ Compile node object to module. """ if node and not isinstance(node, ast.AST): raise TypeError('Unexpected type for node: {}'.format(str(type(node)))) if old_module and not isinstance(old_module, types.ModuleType): raise TypeError('Unexpected type for old_module: {}'.format(str(type(old_module)))) if not isinstance(node, ast.Module): node = ast.copy_location(ast.Module(body = [node]), node) file = file or (inspect.getfile(old_module) if old_module else None) code = _call_with_frames_removed\ ( compile , source = node , filename = file or '<file>' , mode = 'exec' , dont_inherit = True ) module = old_module or types.ModuleType() exec(code, module.__dict__) return module
def ast_to_func(node: ast.AST, old_func: types.FunctionType, file: str = None) -> types.FunctionType: """ Compile node object to function. """ if node and not isinstance(node, (ast.Module, ast.FunctionDef)): raise TypeError('Unexpected type for node: {}'.format(str(type(node)))) if old_func and not isinstance(old_func, types.FunctionType): raise TypeError('Unexpected type for old_func: {}'.format(str(type(old_func)))) result = old_func if node and old_func: old_code = getattr(old_func, '__code__', None) if not isinstance(node, ast.Module): mod_node = ast.copy_location(ast.Module(body = [node]), node) fun_node = node else: mod_node = node fun_node = node.body[0] module = ast_to_code(mod_node, old_code, file=file) for code in module.co_consts: if not isinstance(code, types.CodeType): continue if code.co_name == fun_node.name and code.co_firstlineno == fun_node.lineno: result.__code__ = code break else: raise ValueError('Not specified value') return result
def convert(self, node): code = compile(node, '<string>', mode = 'eval') value = eval(code) new_node = ast.parse(str(value), mode = 'eval') if isinstance(new_node, ast.Expression): new_node = new_node.body new_node = self.generic_visit(new_node) node = ast.copy_location(new_node, node) node = ast.fix_missing_locations(node) return node
def visit_If(self, node): node = self.generic_visit(node) if (node.orelse and len(node.orelse) == 1 and isinstance(node.orelse[0], ast.Pass) ): node.orelse = [] if (len(node.body) == 1 and isinstance(node.body[0], ast.Pass) ): if node.orelse: node_test = ast.UnaryOp(op=ast.Not(), operand=node.test) if (len(node.orelse) == 1 and isinstance(node.orelse[0], ast.If) ): node_test = ast.BoolOp\ ( op = ast.And() , values = [node_test, node.orelse[0].test] ) node.test = ast.copy_location(node_test, node.orelse[0].test) node.body = node.orelse[0].body node.orelse = node.orelse[0].orelse else: node.test = ast.copy_location(node_test, node.test) node.body = node.orelse node.orelse = [] else: node = None return node
def visit_Attribute(self, node: ast.Attribute): if isinstance(node.value, ast.Name): if isinstance(node.ctx, ast.Load): name = '{}.{}'.format(node.value.id, node.attr) if name in self._values: node = ast.copy_location(self._values[name], node) return self.generic_visit(node)
def visit_For(self, node: ast.For): node = self.generic_visit(node) if self._is_for_yield(node): yield_node = ast.YieldFrom(value = node.iter) expr_node = ast.Expr(value = yield_node) node = ast.copy_location(expr_node, node) node = ast.fix_missing_locations(node) return node
def visit_BinOp(self, node: ast.BinOp): node = self.generic_visit(node) if self._is_numeric_pow(node): left, right = node.left, node.right degree = ( right.n if isinstance(right, ast.Num) else -right.operand.n if isinstance(right.op, ast.USub) else right.operand.n ) degree = int(degree) if abs(degree) == 0: node = ast.copy_location(ast.Num(n = 1), node) elif abs(degree) == 1: node = node.left elif 2 <= abs(degree) <= self.MAX_DEGREE: for _ in range(1, abs(degree)): new_node = ast.BinOp\ ( left = left , op = ast.Mult() , right = copy(node.left) ) left = new_node = ast.copy_location(new_node, node) node = new_node else: return node if degree < 0: new_node = ast.BinOp\ ( left = ast.Num(n = 1) , op = ast.Div() , right = node ) node = ast.copy_location(new_node, node) return node
def to_messageable(self, call): if not isinstance(call.func, ast.Attribute): return call if call.func.attr == 'say': if self.interactive and not prompt_change( 'A possible change was found to change say to send.' ): return call call.func.value = ast.Name(id='ctx', ctx=ast.Load()) call.func.attr = 'send' stats_counter['call_changes'] += 1 elif call.func.attr == 'send_message': if self.interactive and not prompt_change( 'A possible change was found to change send_message to send.' ): return call destination = call.args[0] wrap_attr = ast.Attribute() wrap_attr.value = destination wrap_attr.attr = 'send' wrap_attr.ctx = ast.Load() newcall = ast.Call() newcall.func = wrap_attr newcall.args = call.args[1:] newcall.keywords = call.keywords newcall = ast.copy_location(newcall, call) stats_counter['call_changes'] += 1 return newcall return call
def test_copy_location(self): src = ast.parse('1 + 1', mode='eval') src.body.right = ast.copy_location(ast.Num(2), src.body.right) self.assertEqual(ast.dump(src, include_attributes=True), 'Expression(body=BinOp(left=Num(n=1, lineno=1, col_offset=0), ' 'op=Add(), right=Num(n=2, lineno=1, col_offset=4), lineno=1, ' 'col_offset=0))' )
def visit_Expr(self, node): if type(node.value) is ast.Call: call = node.value if self.is_concurrent_call(call): self.encounter_call(call) return node elif any([self.is_concurrent_call(arg) for arg in call.args]): conc_args = [(i, arg) for i, arg in enumerate(call.args) if self.is_concurrent_call(arg)] if len(conc_args) > 1: raise self.not_implemented_error(call, "Functions with multiple @concurrent parameters are unsupported") conc_call = conc_args[0][1] self.encounter_call(conc_call) call.args[conc_args[0][0]] = ast.Name("__value__", ast.Load()) if sys.version_info >= (3, 0): args = [ast.arg("__value__", None)] else: args = [ast.Name("__value__", ast.Param())] call_lambda = ast.Lambda(ast.arguments(args = args, defaults = [], kwonlyargs = [], kw_defaults = []), call) copy_location_kwargs = { "func": ast.Attribute(conc_call.func, 'call', ast.Load()), "args": [call_lambda] + conc_call.args, "keywords": conc_call.keywords } if(sys.version_info < (3, 0)): copy_location_kwargs["kwargs"] = conc_call.kwargs return copy_location(ast.Expr(ast.Call(**copy_location_kwargs)), node) return self.generic_visit(node)
def visit_Assign(self, node): if self.is_valid_assignment(node): call = node.value self.encounter_call(call) name = node.targets[0].value self.arguments.add(SchedulerRewriter.top_level_name(name)) index = node.targets[0].slice.value call.func = ast.Attribute(call.func, 'assign', ast.Load()) call.args = [ast.Tuple([name, index], ast.Load())] + call.args return copy_location(ast.Expr(call), node) return self.generic_visit(node)
def visit_Num(self, node): """ WARNING: you cannot directly write constants in list. It will throw obscure error like "TypeError: required field "lineno" missing from expr" You MUST wrap all constants in ast_demo types, like ast_demo.Num(n=42) instead of raw 42 """ n = node.n if isinstance(n, int): new_node = ast.Call(func=ast.Name(id='Fraction', ctx=ast.Load()), args=[node, ast.Num(n=1)], keywords=[]) ast.copy_location(new_node, node) # ast_demo.fix_missing_locations(new_node) return new_node return node
def visit_Assert(self, node): if isinstance(node.test, ast.Compare) and \ len(node.test.ops) == 1 and \ isinstance(node.test.ops[0], ast.Eq): call = ast.Call(func=ast.Name(id='assert_equal', ctx=ast.Load()), args=[node.test.left, node.test.comparators[0]], keywords=[]) # Wrap the call in an Expr node, because the return value isn't used. newnode = ast.Expr(value=call) ast.copy_location(newnode, node) ast.fix_missing_locations(newnode) return newnode # Return the original node if we don't want to change it. return node