def has(self, node): """ Determine if this node has the given `node`. """ if isinstance(node, (int, float)): visitor = ast.NodeVisitor() has_num = [] def visit_Num(self, potential): has_num.append(node == potential.n) return self.generic_visit(potential) visitor.visit_Num = MethodType(visit_Num, visitor) visitor.visit(self.astNode) return any(has_num) elif node.ast_name != "Name": return False visitor = ast.NodeVisitor() has_name = [] def visit_Name(self, potential): has_name.append(node.id == potential.id) return self.generic_visit(potential) visitor.visit_Name = MethodType(visit_Name, visitor) visitor.visit(self.astNode) return any(has_name)
def has(self, node): """ Determine if this node has the given `node`. Specifically, it checks if the ast has a given Constant or variable This method does NOT check for equality of two asts. Use find_matches for that functionality Args: node (): A constant (int, float, str), or Name astnode Returns: True if found, False otherwise """ if isinstance(node, (int, float, str)): visitor = ast.NodeVisitor() has_constant = [] def visit_Constant(self, potential): has_constant.append(node == potential.value) return self.generic_visit(potential) def visit_Num(self, potential): has_constant.append(node == potential.n) return self.generic_visit(potential) def visit_Str(self, potential): has_constant.append(node == potential.s) return self.generic_visit(potential) visitor.visit_Num = MethodType(visit_Num, visitor) visitor.visit_Constant = MethodType(visit_Constant, visitor) visitor.visit_Str = MethodType(visit_Str, visitor) visitor.visit(self.astNode) return any(has_constant) elif node.ast_name != "Name": return False visitor = ast.NodeVisitor() has_name = [] def visit_Name(self, potential): """ Args: self: potential: Returns: """ has_name.append(node.id == potential.id) return self.generic_visit(potential) visitor.visit_Name = MethodType(visit_Name, visitor) visitor.visit(self.astNode) return any(has_name)
def get_decorators(cls): AVAILABLE_METHODS = ['GET', 'PUT', 'POST', 'DELETE'] PATH = 'PATH' AUTH = 'AUTH' target = cls decorators = {} def visit_fn(node): if node.name[:2] == "__": return decorators[node.name] = {} for n in node.decorator_list: if isinstance(n, ast.Call): name = n.func.attr if isinstance(n.func, ast.Attribute) else n.func.id if name == PATH: decorators[node.name].update(parse_path(n)) elif name == AUTH: decorators[node.name]['authorization'] = True else: name = n.attr if isinstance(n, ast.Attribute) else n.id if name in AVAILABLE_METHODS: decorators[node.name]['method'] = name node_iter = ast.NodeVisitor() node_iter.visit_FunctionDef = visit_fn node_iter.visit(ast.parse(inspect.getsource(target))) return decorators
def __init__(cls, class_name: str, bases: tuple, attrs: dict): """Initialize metrics type.""" def _is_register_metric_job_decorator_present( node: ast.FunctionDef) -> None: """Check if the given function has assigned decorator to register a new metric job.""" n_ids = [ t.id for t in node.decorator_list if isinstance(t, ast.Name) ] for n_id in n_ids: if n_id == register_metric_job.__name__: _LOGGER.info("Registering job %r implemented in %r", method_name, class_name) REGISTERED_JOBS.append((class_name, method_name)) global REGISTERED_JOBS _LOGGER.info("Checking class %r for registered metric jobs", class_name) node_iter = ast.NodeVisitor() # TODO(pacospace) check typing node_iter.visit_FunctionDef = _is_register_metric_job_decorator_present # type: ignore for method_name, item in attrs.items(): # Metrics classes are not instantiable. if isinstance(item, (staticmethod, classmethod)): source = textwrap.dedent(inspect.getsource(item.__func__)) node_iter.visit(ast.parse(source))
def get_heos_decorators(cls=HeosDevice): target = 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 if name in ('HeosEventCallback',): params = list() if len(n.args) == 2: for val in n.args[1].elts: params.append(val.value) decorators[node.name].append({ "name": name, "event": n.args[0].value, "params": params }) if not decorators[node.name]: decorators.pop(node.name) node_iter = ast.NodeVisitor() node_iter.visit_AsyncFunctionDef = visit_FunctionDef node_iter.visit(ast.parse(inspect.getsource(target))) return decorators
def get_functions(source): functions = [] def visit_Call(node): path = node.func.attr if isinstance(node.func, ast.Attribute) else node.func.id if len(node.args) != 0: args = [] for arg in node.args: arg_dict = build_dict(arg) arg_dict.pop("value", None) for val in arg_dict.values(): args.append(str(val)) path += ":" + ":".join(args) if len(node.keywords) != 0: path += ":" + ":".join([ str(val) for keyword in node.keywords for val in build_dict(keyword).values() ]) functions.append(path) node_iter = ast.NodeVisitor() node_iter.visit_Call = visit_Call node_iter.visit(ast.parse(inspect.getsource(source))) return functions
def desc(self): """return the description of this endpoint""" doc = None if self.endpoint: def visit_FunctionDef(node): """ https://docs.python.org/2/library/ast.html#ast.NodeVisitor.visit """ if node.name != self.controller_method_name: return doc = ast.get_docstring(node) raise StopIteration(doc if doc else u"") target = self.endpoint.controller_class try: node_iter = ast.NodeVisitor() node_iter.visit_FunctionDef = visit_FunctionDef node_iter.visit(ast.parse(inspect.getsource(target))) except StopIteration as e: doc = str(e) else: doc = inspect.getdoc(self.controller_method) if not doc: doc = u"" return doc
def _get_next_tree(self): """Gets the next tree in the AST This method gets the next AST node that is of equal or higher level than self. Returns None if the end of the tree is reached TODO: Create a get sibling method. :return: The next tree in the AST """ # adding function to track tree ids def visit_counter(self, node): self.counter += 1 self.generic_visit(node) node_counter = ast.NodeVisitor() setattr(node_counter, 'counter', self.tree_id) node_counter.visit = MethodType(visit_counter, node_counter) # getting ids node_counter.visit(self.astNode) out_of_tree = node_counter.counter >= len( self.linear_tree) # check if out of bounds # len(self.children) > 0 and self.children[-1] == node_counter if out_of_tree: return None return self.linear_tree[node_counter.counter]
def get_decorators(function): """ Fancy introspection - very WIP """ decorators = {} def visit_FunctionDef(node): decorators[node.name] = {} for n in node.decorator_list: print(ast.dump(n)) name = '' if isinstance(n, ast.Call): group = n.func.value.id name = n.func.attr if isinstance(n.func, ast.Attribute) else n.func.id for a in n.args: print(ast.dump(a)) else: group = n.attr if isinstance(n, ast.Attribute) else n.id name = None if group not in decorators[node.name]: decorators[node.name][group] = [] if name: decorators[node.name][group].append({name}) node_iter = ast.NodeVisitor() node_iter.visit_FunctionDef = visit_FunctionDef node_iter.visit(ast.parse(textwrap.dedent(inspect.getsource(function)))) return decorators
def get_decorators(cls: type) -> dict: """Find which decorators are registered for each method in a class or for a function Args: cls: class or function Returns: dict: Dictionary with format {method_name: [decorators]} """ target = cls decorators = {} def visit_function_def(node): decorators[node.name] = [] for n in node.decorator_list: 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 decorators[node.name].append(name) node_iter = ast.NodeVisitor() node_iter.visit_FunctionDef = visit_function_def node_iter.visit(ast.parse(inspect.getsource(target))) return decorators
def find_request_binding(target): """Find `@request` decorated methods in a class. :param target: the target class to check :return: a dictionary with key as request type and value as method name """ import ast, inspect from . import __default_endpoint__ res = {} def visit_function_def(node): for e in node.decorator_list: req_name = '' if isinstance(e, ast.Call) and e.func.id == 'requests': req_name = e.keywords[0].value.s elif isinstance(e, ast.Name) and e.id == 'requests': req_name = __default_endpoint__ if req_name: if req_name in res: raise ValueError( f'you already bind `{res[req_name]}` with `{req_name}` request' ) else: res[req_name] = node.name V = ast.NodeVisitor() V.visit_FunctionDef = visit_function_def V.visit(compile(inspect.getsource(target), '?', 'exec', ast.PyCF_ONLY_AST)) return res
def get_functions_returns(source): returns = [] def visit_Return(node): returns.append(build_dict(node)) node_iter = ast.NodeVisitor() node_iter.visit_Return = visit_Return node_iter.visit(ast.parse(inspect.getsource(source))) return returns
def get_statements(source): statements = [] def visit_If(node): statements.append(build_dict(node)) node_iter = ast.NodeVisitor() node_iter.visit_If = visit_If node_iter.visit(ast.parse(inspect.getsource(source))) return statements
def _find_decorators(cls): v = ast.NodeVisitor() methods_all = dict() def visit_FunctionDef(Node): methods_all[Node.name] = [ast.dump(e) for e in Node.decorator_list] v.visit_FunctionDef = cls.visit_FunctionDef v.visit(compile(inspect.getsource(cls), '?', 'exec', ast.PyCF_ONLY_AST)) return methods_all
def find_deco(cls): result = dict() def visit_FunctionDef(node): result[node.name] = [ast.dump(e) for e in node.decorator_list] v = ast.NodeVisitor() v.visit_FunctionDef = visit_FunctionDef v.visit(compile(inspect.getsource(cls), '?', 'exec', ast.PyCF_ONLY_AST)) return result
def get_functions_returns(source): returns = [] def visit_Return(node): return_dict = build_dict(node) return_dict.pop("value/args/value", None) return_dict.pop("value/args/args/value", None) returns.append(return_dict) node_iter = ast.NodeVisitor() node_iter.visit_Return = visit_Return node_iter.visit(ast.parse(inspect.getsource(source))) return returns
def check_decorator_names(code, expected_names): decorator_names = [] def visit_FunctionDef(node): for decorator in node.decorator_list: decorator_names.append(utils.get_decorator_name(decorator)) node_visitor = ast.NodeVisitor() node_visitor.visit_AsyncFunctionDef = visit_FunctionDef node_visitor.visit_ClassDef = visit_FunctionDef node_visitor.visit_FunctionDef = visit_FunctionDef node_visitor.visit(ast.parse(code)) assert expected_names == decorator_names
def get_if_statements(source, return_type='string', include_type=False): ifs = [] def visit_If(node): ifs.append(convert_ast(node, return_type, include_type)) node_iter = ast.NodeVisitor() node_iter.visit_If = visit_If try: node_iter.visit(ast.parse(inspect.getsource(source))) except OSError: return [] return ifs
def get_for_loops(source, return_type='string', include_type=False): loops = [] def visit_For(node): loops.append(convert_ast(node, return_type, include_type)) node_iter = ast.NodeVisitor() node_iter.visit_For = visit_For try: node_iter.visit(ast.parse(inspect.getsource(source))) except OSError: return [] return loops
def get_calls(source, return_type='string', include_type=False): calls = [] def visit_Call(node): calls.append(convert_ast(node, return_type, include_type)) node_iter = ast.NodeVisitor() node_iter.visit_Call = visit_Call try: node_iter.visit(ast.parse(inspect.getsource(source))) except OSError: return [] return calls
def get_assignments(source, return_type='string', include_type=False): assignments = [] def visit_Assign(node): assignments.append(convert_ast(node, return_type, include_type)) node_iter = ast.NodeVisitor() node_iter.visit_Assign = visit_Assign try: node_iter.visit(ast.parse(inspect.getsource(source))) except OSError: return [] return assignments
def get_functions(source, return_type='string', include_type=False): functions = [] def visit_FunctionDef(node): functions.append(convert_ast(node, return_type, include_type)) node_iter = ast.NodeVisitor() node_iter.visit_FunctionDef = visit_FunctionDef try: node_iter.visit(ast.parse(inspect.getsource(source))) except OSError: return [] return functions
def get_returns_from_child(child_node, return_type='string', include_type=False): returns = [] def visit_Return(node): returns.append(convert_ast(node, return_type, include_type)) node_iter = ast.NodeVisitor() node_iter.visit_Return = visit_Return try: node_iter.visit(child_node) #ast.parse(inspect.getsource(source))) except OSError: return [] return returns
def parse_properties_from_source(module_src): # pylint: disable=R0912 '''we need to find the task parameters, such that we can serve a them for the gui generation. However, we don't want to load the module, because we can't trust the code. So we parse the AST instead From: http://stackoverflow.com/a/9580006 ''' import ast def visit_FunctionDef(node): '''visitor to function definitions, needed to extract decorator''' for e in node.decorator_list: assert isinstance(e, (ast.Call, ast.Name)) decorator_name = '' if isinstance(e, ast.Call): # @task(args, ...) decorator_name = e.func.id elif isinstance(e, ast.Name): # @task [ie: naked] decorator_name = e.id if 'task' == decorator_name: visit_FunctionDef.task_count += 1 visit_FunctionDef.function_name = node.name visit_FunctionDef.function_params = [ to.parse_val(arg) for arg in node.args.args ] visit_FunctionDef.doc = ast.get_docstring(node) or '' visit_FunctionDef.function_name = None visit_FunctionDef.function_params = [] visit_FunctionDef.doc = '' visit_FunctionDef.task_count = 0 # number of decorators named task visitor = ast.NodeVisitor() visitor.visit_FunctionDef = visit_FunctionDef visitor.visit(compile(module_src, '?', 'exec', ast.PyCF_ONLY_AST)) if 0 == visit_FunctionDef.task_count: raise ValueError('Task has no @task decorator') elif 1 < visit_FunctionDef.task_count: raise ValueError('Task has too many @task decorators') return visit_FunctionDef.function_name, visit_FunctionDef.function_params, visit_FunctionDef.doc
def parse_code(): # Spezifikation Code: Der Code enthält 2 Funktionen: Einer zum preprocessen und der andere zur Modeldefinition # Die Reihenfolge ist: 1.testsplit 2.Modeldef # Dies ist wichtig da wir hier die Funktionen mit Hilfe des ast auslesen und von der Reihenfolge ausgehen # Außerdem kriegen die Funktionen folgene Parameter: Test_split(dataframe) und Modeldef(X_train, X_test, y_train, y_test) # Folgende Rückgabewerte gibts für die Fkt.: Test_split=>dataframe,Encoder und Modeldef=>modeldef,int: Klassifikationstyp file = open(file_pathf, 'r') funcs = [] text = file.read() p = ast.parse(text) # Create AST node = ast.NodeVisitor() # GET funcs with AST for node in ast.walk(p): if isinstance(node, ast.FunctionDef): funcs.append(node.name) return funcs
def get_types_decorator(cls): target = cls decorators = {} def visit_FunctionDef(node): 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 if name == 'types': decorators[node.name] = [i.s for i in n.args] node_iter = ast.NodeVisitor() node_iter.visit_FunctionDef = visit_FunctionDef node_iter.visit(ast.parse(inspect.getsource(target))) return decorators
def get_decorators(source): 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 node_iter.visit(ast.parse(inspect.getsource(source))) return decorators
def get_decorators(cls): target = 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 decorators[node.name].append(name) node_iter = ast.NodeVisitor() node_iter.visit_FunctionDef = visit_FunctionDef node_iter.visit(ast.parse(inspect.getsource(target))) return decorators
def get_decorated_functions( self, classdef: ast.ClassDef, decorator: Decorator) -> Dict[cppast.DeclRefExpr, ast.FunctionDef]: visitor = ast.NodeVisitor() functions: Dict[cppast.DeclRefExpr, ast.FunctionDef] = {} def visit_FunctionDef(node: ast.FunctionDef): if node.decorator_list: node_decorator: str = visitors_util.get_node_name( node.decorator_list[0]) if decorator.value == node_decorator: functions[cppast.DeclRefExpr(node.name)] = node visitor.visit_FunctionDef = visit_FunctionDef for method in classdef.body: visitor.visit(method) return functions
def get_annotated_functions( decorator: Decorator) -> Dict[str, ast.FunctionDef]: visitor = ast.NodeVisitor() functions: Dict[str, ast.FunctionDef] = {} def visit_FunctionDef(node): if node.decorator_list: try: node_decorator: str = node.decorator_list[0].id except AttributeError: node_decorator: str = node.decorator_list[0].attr if decorator.value == node_decorator: functions[node.name] = node visitor.visit_FunctionDef = visit_FunctionDef for method in classdef.body: visitor.visit(method) return functions