我们从Python开源项目中,提取了以下50个代码示例,用于说明如何使用ast.Attribute()。
def _is_list_iter(self): """ Test if the current statement is a type of list, used in for loops. """ # Check for literal or memory list. iter_var_type = self.context.vars.get(self.stmt.iter.id).typ if isinstance(self.stmt.iter, ast.Name) else None if isinstance(self.stmt.iter, ast.List) or isinstance(iter_var_type, ListType): return True # Check for storage list. if isinstance(self.stmt.iter, ast.Attribute): iter_var_type = self.context.globals.get(self.stmt.iter.attr) if iter_var_type and isinstance(iter_var_type.typ, ListType): return True return False
def get_target(self, target): if isinstance(target, ast.Subscript) and self.context.in_for_loop: # Check if we are doing assignment of an iteration loop. raise_exception = False if isinstance(target.value, ast.Attribute): list_name = "%s.%s" % (target.value.value.id, target.value.attr) if list_name in self.context.in_for_loop: raise_exception = True if isinstance(target.value, ast.Name) and \ target.value.id in self.context.in_for_loop: list_name = target.value.id raise_exception = True if raise_exception: raise StructureException("Altering list '%s' which is being iterated!" % list_name, self.stmt) if isinstance(target, ast.Name) and target.id in self.context.forvars: raise StructureException("Altering iterator '%s' which is in use!" % target.id, self.stmt) target = Expr.parse_variable_location(target, self.context) if target.location == 'storage' and self.context.is_constant: raise ConstancyViolationException("Cannot modify storage inside a constant function: %s" % target.annotation) if not target.mutable: raise ConstancyViolationException("Cannot modify function argument: %s" % target.annotation) return target
def __init__(self, expr, context): self.expr = expr self.context = context self.expr_table = { LLLnode: self.get_expr, ast.Num: self.number, ast.Str: self.string, ast.NameConstant: self.constants, ast.Name: self.variables, ast.Attribute: self.attribute, ast.Subscript: self.subscript, ast.BinOp: self.arithmetic, ast.Compare: self.compare, ast.BoolOp: self.boolean_operations, ast.UnaryOp: self.unary_operations, ast.Call: self.call, ast.List: self.list_literals, ast.Dict: self.struct_literals, ast.Tuple: self.tuple_literals, } expr_type = self.expr.__class__ if expr_type in self.expr_table: self.lll_node = self.expr_table[expr_type]() else: raise Exception("Unsupported operator: %r" % ast.dump(self.expr))
def get_decorators(cls): decorators = {} def visit_FunctionDef(node): decorators[node.name] = [] for n in node.decorator_list: name = '' if isinstance(n, ast.Call): name = n.func.attr if isinstance(n.func, ast.Attribute) else n.func.id else: name = n.attr if isinstance(n, ast.Attribute) else n.id args = [a.s for a in n.args] if hasattr(n, 'args') else [] decorators[node.name].append((name, args)) node_iter = ast.NodeVisitor() node_iter.visit_FunctionDef = visit_FunctionDef _cls = cls if inspect.isclass(cls) else cls.__class__ node_iter.visit(ast.parse(inspect.getsource(_cls))) return decorators
def visit_Call(self, node): # This will not visit Flask in Flask(__name__) but it will visit request in `request.args.get() if not isinstance(node.func, ast.Name): self.visit(node.func) for arg in itertools.chain(node.args, node.keywords): if isinstance(arg, ast.Call): if isinstance(arg.func, ast.Name): # We can't just visit because we need to add 'ret_' self.result.append('ret_' + arg.func.id) elif isinstance(arg.func, ast.Attribute): # e.g. html.replace('{{ param }}', param) # func.attr is replace # func.value.id is html # We want replace self.result.append('ret_' + arg.func.attr) else: # Deal with it when we have code that triggers it. raise else: self.visit(arg)
def _get_attribute_full_path(self, node): """Traverse an attribute to generate a full name e.g. tf.foo.bar. Args: node: A Node of type Attribute. Returns: a '.'-delimited full-name or None if the tree was not a simple form. i.e. `foo()+b).bar` returns None, while `a.b.c` would return "a.b.c". """ curr = node items = [] while not isinstance(curr, ast.Name): if not isinstance(curr, ast.Attribute): return None items.append(curr.attr) curr = curr.value items.append(curr.id) return ".".join(reversed(items))
def visit_Attribute(self, node): # pylint: disable=invalid-name """Handle bare Attributes i.e. [tf.foo, tf.bar]. Args: node: Node that is of type ast.Attribute """ full_name = self._get_attribute_full_path(node) if full_name and full_name.startswith("tf."): self._rename_functions(node, full_name) if full_name in self._api_change_spec.change_to_function: if not hasattr(node, "is_function_for_call"): new_text = full_name + "()" self._file_edit.add("Changed %r to %r"%(full_name, new_text), node.lineno, node.col_offset, full_name, new_text) ast.NodeVisitor.generic_visit(self, node)
def match_type(self, typ, node): if typ == 'class': return isinstance(node, ast.ClassDef) if typ == 'def': return isinstance(node, ast.FunctionDef) if typ == 'import': return isinstance(node, (ast.Import, ast.ImportFrom)) if typ == 'assign': return isinstance(node, ast.Assign) if typ == 'attr': return isinstance(node, ast.Attribute) if typ == 'call': if isinstance(node, ast.Call): return True # Python 2.x compatibility return hasattr(ast, 'Print') and isinstance(node, ast.Print)
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 channel_history(self, call): if isinstance(call.func, ast.Attribute): if call.func.attr == 'logs_from': if self.interactive and not prompt_change( 'A possible change was found to change logs_from to history.' ): return call dest = call.args[0] call.args = call.args[1:] if call.args: limit = call.args[0] call.keywords.append(ast.keyword(arg='limit', value=limit)) call.args = [] call.func.value = dest call.func.attr = 'history' stats_counter['call_changes'] += 1 return call
def stateful_create_channel(self, call): if isinstance(call.func, ast.Attribute): if call.func.attr == 'create_channel': if self.interactive and not prompt_change( 'A possible change was found to make {} stateful.'.format(call.func.attr) ): return call for kw in list(call.keywords): if isinstance(kw.value, ast.Attribute): channel_type = kw.value.attr call.keywords.remove(kw) break else: channel_type = 'text' call.func.attr = 'create_{}_channel'.format(channel_type) guild = call.args[0] call.func.value = guild stats_counter['call_changes'] += 1 return call
def stateful_pin_message(self, call): if isinstance(call.func, ast.Attribute): if call.func.attr == 'pin_message': if self.interactive and not prompt_change( 'A possible change was found to make {} stateful.'.format(call.func.attr) ): return call message = call.args[0] call.func.value = message call.func.attr = 'pin' call.args = [] elif call.func.attr == 'unpin_message': if self.interactive and not prompt_change( 'A possible change was found to make {} stateful.'.format(call.func.attr) ): return call message = call.args[0] call.func.value = message call.func.attr = 'unpin' call.args = [] stats_counter['call_changes'] += 1 return call
def parse_args(args): arg_list = [] for arg in args: if isinstance(arg, ast.Str): arg_list.append("%s" % arg.s) elif isinstance(arg, ast.Name): value = arg.id if value == "None": arg_list.append(None) else: arg_list.append(value) elif isinstance(arg, ast.Num): arg_list.append(arg.n) elif isinstance(arg, ast.List): arg_list.append(parse_args(arg.elts)) elif isinstance(arg, ast.Tuple): arg_list.append(tuple(parse_args(arg.elts))) elif isinstance(arg, ast.Attribute): arg_list.append(str(arg.value.id) + "." + str(arg.attr)) else: print(arg, type(arg)) return arg_list
def visit_Attribute(self, node): # type: (ast.Attribute) -> None self.generic_visit(node) lhs_inferred_type = self._get_inferred_type_for_node(node.value) if lhs_inferred_type is None: return elif lhs_inferred_type == Boto3ModuleType(): # Check for attributes such as boto3.client. if node.attr == self._CREATE_CLIENT: # This is a "boto3.client" attribute. self._set_inferred_type_for_node(node, Boto3CreateClientType()) elif isinstance(lhs_inferred_type, Boto3ClientType): self._set_inferred_type_for_node( node, Boto3ClientMethodType( lhs_inferred_type.service_name, node.attr ) )
def _is_chalice_view(self, node): # type: (ast.FunctionDef) -> bool # We can certainly improve on this, but this check is more # of a heuristic for the time being. The ideal way to do this # is to infer the Chalice type and ensure the function is # decorated with the Chalice type's route() method. decorator_list = node.decorator_list if not decorator_list: return False for decorator in decorator_list: if isinstance(decorator, ast.Call) and \ isinstance(decorator.func, ast.Attribute): if decorator.func.attr == 'route' and \ decorator.args: return True # For lambda_function and schedule decorator.args # not present. if decorator.func.attr in ('lambda_function', 'schedule'): return True return False
def visit_Attribute(self, node): # pylint: disable=invalid-name """Handle bare Attributes i.e. [tf.foo, tf.bar]. Args: node: Node that is of type ast.Attribute """ full_name = self._get_attribute_full_path(node) if full_name: self._rename_functions(node, full_name) if full_name in self._api_change_spec.change_to_function: if not hasattr(node, "is_function_for_call"): new_text = full_name + "()" self._file_edit.add("Changed %r to %r"%(full_name, new_text), node.lineno, node.col_offset, full_name, new_text) ast.NodeVisitor.generic_visit(self, node)
def get_qual_attr(node, aliases): prefix = "" if isinstance(node, _ast.Attribute): try: val = deepgetattr(node, 'value.id') if val in aliases: prefix = aliases[val] else: prefix = deepgetattr(node, 'value.id') except Exception: # NOTE(tkelsey): degrade gracefully when we can't get the fully # qualified name for an attr, just return its base name. pass return "%s.%s" % (prefix, node.attr) else: return "" # TODO(tkelsey): process other node types
def traversal_via_tarfile_extractall(context): call_node = context.node if not isinstance(call_node.func, ast.Attribute): return if not isinstance(call_node.func.value, ast.Name): return name = s_utils.get_attribute_name(call_node.func) if not (name and name.endswith('.extractall')): return if not s_utils.method_could_be_class(call_node, context, ('tarfile.open',)): return return bandit.Issue( severity=bandit.MEDIUM, confidence=bandit.HIGH, text='Use of tarfile.extractall() can result in files being written to arbitrary locations on the file system.' )
def get_attr_key(self, node): assert isinstance(node, ast.Attribute), 'attribute node expected' return '%s.%s' % (node.value.id, node.attr)
def do_compare(self, node): def sanity_check(lhsnode, rhsnode): valid = True if isinstance(lhsnode, ast.Str) and isinstance(rhsnode, ast.Str): valid = False #elif (isinstance(lhsnode, ast.Attribute) # and isinstance(rhsnode, ast.Attribute)): # klhs = self.get_attr_key(lhsnode) # krhs = self.get_attr_key(rhsnode) # valid = klhs != krhs if not valid: s = self.get_fragment(node.col_offset) raise SyntaxError('Invalid comparison: %s' % s) lhsnode = node.left lhs = self.evaluate(lhsnode) result = True for op, rhsnode in zip(node.ops, node.comparators): sanity_check(lhsnode, rhsnode) op = op.__class__.__name__.lower() if op not in self.operators: raise SyntaxError('unsupported operation: %r' % op) rhs = self.evaluate(rhsnode) result = self.operators[op](lhs, rhs) if not result: break lhs = rhs lhsnode = rhsnode return result
def visit_ListComp(self, t): result_append = ast.Attribute(ast.Name('.0', load), 'append', load) body = ast.Expr(Call(result_append, [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('.0', load))] args = ast.arguments([ast.arg('.0', None)], None, [], None, [], []) return Call(Function('<listcomp>', args, fn), [ast.List([], load)])
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 get_sink_args(cfg_node): if type(cfg_node) == AssignmentNode: return get_sink_args(cfg_node.ast_node.value) elif type(cfg_node) == ReturnNode: return get_sink_args(cfg_node.ast_node.value) elif isinstance(cfg_node, Node): return get_sink_args(cfg_node.ast_node) elif isinstance(cfg_node, ast.Call): args = list() for arg in cfg_node.args + cfg_node.keywords: if isinstance(arg, ast.Name): args.append(arg.id) elif isinstance(arg, ast.Str): args.append(arg.s) elif isinstance(arg, ast.Call): args.extend(get_sink_args(arg)) elif isinstance(arg, ast.keyword): args.append(arg.value) elif isinstance(arg, ast.Attribute): import ast_helper args.append(ast_helper.get_call_names_as_string(arg)) else: raise Exception('Unexpected argument type:', type(arg)) return args elif isinstance(cfg_node, ast.Str): return None else: raise Exception('Unexpected node type:', type(cfg_node))