我们从Python开源项目中,提取了以下50个代码示例,用于说明如何使用ast.ClassDef()。
def get_contracts_and_defs_and_globals(code): _contracts = {} _events = [] _globals = {} _defs = [] _getters = [] for item in code: # Contract references if isinstance(item, ast.ClassDef): if _events or _globals or _defs: raise StructureException("External contract declarations must come before event declarations, global declarations, and function definitions", item) _contracts[item.name] = add_contract(item.body) # Statements of the form: # variable_name: type elif isinstance(item, ast.AnnAssign): _contracts, _events, _globals, _getters = add_globals_and_events(_contracts, _defs, _events, _getters, _globals, item) # Function definitions elif isinstance(item, ast.FunctionDef): _defs.append(item) else: raise StructureException("Invalid top-level statement", item) return _contracts, _events, _defs + _getters, _globals # Header code
def visit_Call(self, node): _id = get_call_names_as_string(node.func) self.function_return_stack.append(_id) logging.debug(_id) ast_node = None local_definitions = self.module_definitions_stack[-1] definition = local_definitions.get_definition(_id) if definition: if isinstance(definition.node, ast.ClassDef): init = local_definitions.get_definition(_id + '.__init__') self.add_builtin(node) elif isinstance(definition.node, ast.FunctionDef): self.undecided = False return self.add_function(node, definition) else: raise Exception('Definition was neither FunctionDef or ClassDef, cannot add the function ') return self.add_builtin(node)
def class_to_ast(class_: type, file: str = None) -> ast.ClassDef: """ """ if class_ and not isinstance(class_, type): raise TypeError('Unexpected type: {}'.format(str(type(class_)))) result = None try: src = inspect.getsource(class_) file = file or inspect.getfile(class_) result = source_to_ast(src, file) except IOError: pass return result
def ast_to_class(node: ast.AST, old_class: type = None, file: str = None) -> type: """ :param node: :param old_class: :param file: :return: """ if node and not isinstance(node, (ast.Module, ast.ClassDef)): raise TypeError('Unexpected type for node: {}'.format(str(type(node)))) if old_class and not isinstance(old_class, type): raise TypeError('Unexpected type for old_class: {}'.format(str(type(old_class)))) result = old_class # @TODO: raise NotImplementedError return NotImplemented
def createNameMap(a, d=None): if d == None: d = { } if not isinstance(a, ast.AST): return d if type(a) == ast.Module: # Need to go through the functions backwards to make this right for i in range(len(a.body) - 1, -1, -1): createNameMap(a.body[i], d) return d if type(a) in [ast.FunctionDef, ast.ClassDef]: if hasattr(a, "originalId") and a.name not in d: d[a.name] = a.originalId elif type(a) == ast.arg: if hasattr(a, "originalId") and a.arg not in d: d[a.arg] = a.originalId return d elif type(a) == ast.Name: if hasattr(a, "originalId") and a.id not in d: d[a.id] = a.originalId return d for child in ast.iter_child_nodes(a): createNameMap(child, d) return d
def occursIn(sub, super): """Does the first AST occur as a subtree of the second?""" superStatementTypes = [ ast.Module, ast.Interactive, ast.Suite, ast.FunctionDef, ast.ClassDef, ast.For, ast.While, ast.If, ast.With, ast.Try, ast.ExceptHandler ] if (not isinstance(super, ast.AST)): return False if type(sub) == type(super) and compareASTs(sub, super, checkEquality=True) == 0: return True # we know that a statement can never occur in an expression # (or in a non-statement-holding statement), so cut the search off now to save time. if isStatement(sub) and type(super) not in superStatementTypes: return False for child in ast.iter_child_nodes(super): if occursIn(sub, child): return True return False
def varse(node): vv = VarsVisitor() if isinstance(node.ast_node, ast.FunctionDef) or\ isinstance(node.ast_node, ast.ClassDef): return list() elif isinstance(node.ast_node, ast.While)\ or isinstance(node.ast_node, ast.If): vv.visit(node.ast_node.test) else: try: vv.visit(node.ast_node) except AttributeError: return list() if isinstance(node, AssignmentNode): result = list() for var in vv.result: if var not in node.left_hand_side: result.append(var) return result else: return vv.result
def test_classes_with_specific_method(self): matches1 = list(self.m.match('class:not(:has(def))', self.filepath('classes.py'))) matches2 = list(self.m.match('class:has(def[name=bar])', self.filepath('classes.py'))) matches3 = list(self.m.match('class:has(> def)', self.filepath('classes.py'))) self.assertEqual(len(matches1), 1) self.assertIsInstance(matches1[0][0], ast.ClassDef) self.assertEqual(len(matches2), 3) self.assertIsInstance(matches2[0][0], ast.ClassDef) self.assertIsInstance(matches2[1][0], ast.ClassDef) self.assertIsInstance(matches2[2][0], ast.ClassDef) self.assertEqual(len(matches3), 2) self.assertIsInstance(matches3[0][0], ast.ClassDef) self.assertIsInstance(matches3[1][0], ast.ClassDef) self.assertEqual(matches3[0][1], 1) self.assertEqual(matches3[1][1], 14)
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 _get_module_commands(module): # type: (ast.Module) -> typing.Generator[_EntryPoint, None, None] """Yield all Command objects represented by the python module. Module commands consist of a docopt-style module docstring and a callable Command class. Args: module: An ast.Module object used to retrieve docopt-style commands. Yields: Command objects that represent entry points to append to setup.py. """ cls = next((n for n in module.body if isinstance(n, ast.ClassDef) and n.name == 'Command'), None) if not cls: return methods = (n.name for n in cls.body if isinstance(n, ast.FunctionDef)) if '__call__' not in methods: return docstring = ast.get_docstring(module) for commands, _ in usage.parse_commands(docstring): yield _EntryPoint(commands[0], next(iter(commands[1:]), None), None)
def _get_class_commands(module): # type: (ast.Module) -> typing.Generator[_EntryPoint, None, None] """Yield all Command objects represented by python classes in the module. Class commands are detected by inspecting all callable classes in the module for docopt-style docstrings. Args: module: An ast.Module object used to retrieve docopt-style commands. Yields: Command objects that represent entry points to append to setup.py. """ nodes = (n for n in module.body if isinstance(n, ast.ClassDef)) for cls in nodes: methods = (n.name for n in cls.body if isinstance(n, ast.FunctionDef)) if '__call__' in methods: docstring = ast.get_docstring(cls) for commands, _ in usage.parse_commands(docstring): yield _EntryPoint(commands[0], next(iter(commands[1:]), None), cls.name)
def check_assignment(self, statement): is_class_def = False if type(statement.__flake8_builtins_parent) is ast.ClassDef: is_class_def = True for element in statement.targets: if isinstance(element, ast.Name) and \ element.id in BUILTINS: line = element.lineno offset = element.col_offset if is_class_def: msg = self.class_attribute_msg else: msg = self.assign_msg yield ( line, offset, msg.format(element.id), type(self), )
def method_could_be_class(node, context, search_classes): if isinstance(node, ast.Call): call_node = node parent = get_top_parent_node(call_node) klass_found = next( (klass for klass in iter_method_classes(parent, call_node, context) if klass in search_classes), None ) return klass_found is not None elif isinstance(node, ast.FunctionDef): klass_node = node.parent if not isinstance(klass_node, ast.ClassDef): # not sure what happened here return False for base_klass in klass_node.bases: base_klass = base_klass.id if base_klass in search_classes: return True if name_is_imported(base_klass, context, search_classes): return True else: raise ValueError('node must be either an ast.Call or ast.FunctionDef instance')
def test_classdef(self): def cls(bases=None, keywords=None, starargs=None, kwargs=None, body=None, decorator_list=None): if bases is None: bases = [] if keywords is None: keywords = [] if body is None: body = [ast.Pass()] if decorator_list is None: decorator_list = [] return ast.ClassDef("myclass", bases, keywords, starargs, kwargs, body, decorator_list) self.stmt(cls(bases=[ast.Name("x", ast.Store())]), "must have Load context") self.stmt(cls(keywords=[ast.keyword("x", ast.Name("x", ast.Store()))]), "must have Load context") self.stmt(cls(starargs=ast.Name("x", ast.Store())), "must have Load context") self.stmt(cls(kwargs=ast.Name("x", ast.Store())), "must have Load context") self.stmt(cls(body=[]), "empty body on ClassDef") self.stmt(cls(body=[None]), "None disallowed") self.stmt(cls(decorator_list=[ast.Name("x", ast.Store())]), "must have Load context")
def CONTINUE(self, node): # Walk the tree up until we see a loop (OK), a function or class # definition (not OK), for 'continue', a finally block (not OK), or # the top module scope (not OK) n = node while hasattr(n, 'parent'): n, n_child = n.parent, n if isinstance(n, LOOP_TYPES): # Doesn't apply unless it's in the loop itself if n_child not in n.orelse: return if isinstance(n, (ast.FunctionDef, ast.ClassDef)): break # Handle Try/TryFinally difference in Python < and >= 3.3 if hasattr(n, 'finalbody') and isinstance(node, ast.Continue): if n_child in n.finalbody: self.report(messages.ContinueInFinally, node) return if isinstance(node, ast.Continue): self.report(messages.ContinueOutsideLoop, node) else: # ast.Break self.report(messages.BreakOutsideLoop, node)
def get_compound_bodies(node): """Returns a list of bodies of a compound statement node. Args: node: AST node. Returns: A list of bodies of the node. If the given node does not represent a compound statement, an empty list is returned. """ if isinstance(node, (ast.Module, ast.FunctionDef, ast.ClassDef, ast.With)): return [node.body] elif isinstance(node, (ast.If, ast.While, ast.For)): return [node.body, node.orelse] elif PY2 and isinstance(node, ast.TryFinally): return [node.body, node.finalbody] elif PY2 and isinstance(node, ast.TryExcept): return [node.body, node.orelse] + [h.body for h in node.handlers] elif PY3 and isinstance(node, ast.Try): return ([node.body, node.orelse, node.finalbody] + [h.body for h in node.handlers]) end return []
def check_methods_per_class(self, **kwargs): """ Inspect the code for too many methods per class. """ try: methods_per_class = kwargs['methods_per_class'] except KeyError: return klass = self.parsed_code.body[0] if not isinstance(klass, ast.ClassDef): return methods = [(node, node.lineno) for node in ast.walk(klass) if isinstance(node, ast.FunctionDef)] try: # Get the last method of the class # and its line number: line_number = methods[-1][1] self.issues[line_number].add( self.code_errors.too_many_methods_per_class( len(methods), methods_per_class ) ) except IndexError: return
def infer_file(tree, solver, used_names, infer_func, method_type=None): # Infer only structs that are used in the program to be inferred # Function definitions relevant_nodes = StubsHandler.get_relevant_nodes(tree, used_names) # Only give class definitions to the context to prevent the creation of Z3 constants for stub functions context = Context([stmt for stmt in tree.body if isinstance(stmt, ast.ClassDef)], solver) if method_type: # Add the flag in the statements to recognize the method statements during the inference for node in relevant_nodes: node.method_type = method_type for stmt in relevant_nodes: infer_func(stmt, context, solver) return context
def file_contains_pluggable(file_path, pluggable): plugin_class = None try: with open(file_path, "r") as f: syntax_tree = ast.parse(f.read()) except FileNotFoundError: return [False, None] for statement in ast.walk(syntax_tree): if isinstance(statement, ast.ClassDef): class_name = statement.name bases = list(map(lambda b: b.id if isinstance(b, ast.Name) else b.attr, statement.bases)) if pluggable in bases: plugin_class = class_name return [plugin_class is not None, plugin_class]
def get_all_filters(): """Return all the available filters""" return ( # TODO: Add ast.Module to the docstring search. DocString('d', 'doc', (ast.FunctionDef, ast.ClassDef, ast.Module), help="Match class and function docstrings."), NameFilter('c', 'class', (ast.ClassDef, ), help="Match class names."), DefFilter('f', 'def', (ast.FunctionDef, ), (ast.AST, ), help="Match all defs."), DefFilter('F', 'function', (ast.FunctionDef, ), (ast.Module, ), help="Match function names at the module level."), DefFilter('m', 'method', (ast.FunctionDef, ), (ast.ClassDef, ), help="Match class method names."), DefFilter('j', 'closure', (ast.FunctionDef, ), (ast.FunctionDef, ), help="Match closure def names."), ImportFilter('i', 'import', (ast.Import, ast.ImportFrom, ), help="Match imported package names."), CallFilter('C', 'call', (ast.Call, ), help="Match call statements."), AttrFilter('a', 'attr', (ast.Attribute, ), help="Match attributes on objects"), )
def _generate_nodes(parent, level=0, breadcrumb=''): nodes = [] for child in parent.body: if isinstance(child, ast.ClassDef): style = OutlineNodeItem.Style.cls elif isinstance(child, ast.FunctionDef): style = OutlineNodeItem.Style.fn else: style = None if style: node = OutlineNodeItem(style, child.name, child.lineno, child.col_offset, level, breadcrumb) nodes.append(node) if breadcrumb: bc = '{} • {}'.format(breadcrumb, child.name) else: bc = child.name child_nodes = OutlineDataSource._generate_nodes(child, level + 1, bc) if child_nodes: nodes.extend(child_nodes) return nodes
def is_overridden(self, node, name=None): if not isinstance(node.parent, ast.ClassDef): raise MutationResign() if not name: name = node.name parent = node.parent parent_names = [] while parent: if not isinstance(parent, ast.Module): parent_names.append(parent.name) if not isinstance(parent, ast.ClassDef) and not isinstance(parent, ast.Module): raise MutationResign() parent = parent.parent getattr_rec = lambda obj, attr: functools.reduce(getattr, attr, obj) try: klass = getattr_rec(self.module, reversed(parent_names)) except AttributeError: raise MutationResign() for base_klass in type.mro(klass)[1:-1]: if hasattr(base_klass, name): return True return False
def mutate_FunctionDef(self, node): if not isinstance(node.parent, ast.ClassDef): raise MutationResign() for decorator in node.decorator_list: if isinstance(decorator, ast.Call): decorator_name = decorator.func.id elif isinstance(decorator, ast.Attribute): decorator_name = decorator.value.id else: decorator_name = decorator.id if decorator_name == self.get_decorator_name(): raise MutationResign() decorator = ast.Name(id=self.get_decorator_name(), ctx=ast.Load()) node.decorator_list.append(decorator) return node
def get_coverable_nodes(cls): return { ast.Assert, ast.Assign, ast.AugAssign, ast.Break, ast.Continue, ast.Delete, ast.Expr, ast.Global, ast.Import, ast.ImportFrom, ast.Nonlocal, ast.Pass, ast.Raise, ast.Return, ast.FunctionDef, ast.ClassDef, ast.TryExcept, ast.TryFinally, ast.ExceptHandler, ast.If, ast.For, ast.While, }
def _pos_in_src(self): """Return the position in source of the generated node.""" py_node = self.node.py_node if py_node: offset = getattr(py_node, 'col_offset', 0) # multi-line comments have an offset of -1 if offset < 0: offset = 0 # special handling of nodes that are decorable. Those nodes expose # a 'lineno' that starts with the first decorator. for now, take # the last decorator lineno and add one if isinstance(py_node, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef)) and py_node.decorator_list: result = (py_node.decorator_list[-1].lineno + 1, offset) else: result = (getattr(py_node, 'lineno', None), offset) else: result = (None, None) return result
def run_in_context(code, context, defs={}): ast_ = ast.parse(code, '<code>', 'exec') last_expr = None last_def_name = None for field_ in ast.iter_fields(ast_): if 'body' != field_[0]: continue if len(field_[1]) > 0: le = field_[1][-1] if isinstance(le, ast.Expr): last_expr = ast.Expression() last_expr.body = field_[1].pop().value elif isinstance(le, (ast.FunctionDef, ast.ClassDef)): last_def_name = le.name exec(compile(ast_, '<hbi-code>', 'exec'), context, defs) if last_expr is not None: return eval(compile(last_expr, '<hbi-code>', 'eval'), context, defs) elif last_def_name is not None: return defs[last_def_name] return None
def visit_Assign(self, node): if isinstance(self.node_stack[-2], ast.ClassDef): # note: by hasattr below we're ignoring starred arguments, slices # and tuples for simplicity. assign_targets = {t.id for t in node.targets if hasattr(t, 'id')} if '__metaclass__' in assign_targets: self.errors.append( B303(node.lineno, node.col_offset) ) elif len(node.targets) == 1: t = node.targets[0] if isinstance(t, ast.Attribute) and isinstance(t.value, ast.Name): if (t.value.id, t.attr) == ('os', 'environ'): self.errors.append( B003(node.lineno, node.col_offset) ) self.generic_visit(node)
def get_object_name(obj): """ Return the name of a given object """ name_dispatch = { ast.Name: "id", ast.Attribute: "attr", ast.Call: "func", ast.FunctionDef: "name", ast.ClassDef: "name", ast.Subscript: "value", } # This is a new ast type in Python 3 if hasattr(ast, "arg"): name_dispatch[ast.arg] = "arg" while not isinstance(obj, str): assert type(obj) in name_dispatch obj = getattr(obj, name_dispatch[type(obj)]) return obj
def updateVariableNames(a, varMap, scopeName, randomCounter, imports): if not isinstance(a, ast.AST): return if type(a) in [ast.FunctionDef, ast.ClassDef]: if a.name in varMap: if not hasattr(a, "originalId"): a.originalId = a.name a.name = varMap[a.name] anonymizeStatementNames(a, varMap, "_" + a.name, imports) elif type(a) == ast.arg: if a.arg not in varMap and not (builtInName(a.arg) or importedName(a.arg, imports)): log("Can't assign to arg?", "bug") if a.arg in varMap: if not hasattr(a, "originalId"): a.originalId = a.arg if varMap[a.arg][0] == "r": a.randomVar = True # so we know it can crash if a.arg == varMap[a.arg]: # Check whether this is a given name if not isAnonVariable(varMap[a.arg]): a.dontChangeName = True a.arg = varMap[a.arg] elif type(a) == ast.Name: if a.id not in varMap and not (builtInName(a.id) or importedName(a.id, imports)): varMap[a.id] = "r" + str(randomCounter[0]) + scopeName randomCounter[0] += 1 if a.id in varMap: if not hasattr(a, "originalId"): a.originalId = a.id if varMap[a.id][0] == "r": a.randomVar = True # so we know it can crash if a.id == varMap[a.id]: # Check whether this is a given name if not isAnonVariable(varMap[a.id]): a.dontChangeName = True a.id = varMap[a.id] else: for child in ast.iter_child_nodes(a): updateVariableNames(child, varMap, scopeName, randomCounter, imports)
def staticVars(l, vars): """Determines whether the given lines change the given variables""" # First, if one of the variables can be modified, there might be a problem mutableVars = [] for var in vars: if (not (hasattr(var, "type") and (var.type in [int, float, str, bool]))): mutableVars.append(var) for i in range(len(l)): if type(l[i]) == ast.Assign: for var in vars: if var.id in allVariableNamesUsed(l[i].targets[0]): return False elif type(l[i]) == ast.AugAssign: for var in vars: if var.id in allVariableNamesUsed(l[i].target): return False elif type(l[i]) in [ast.If, ast.While]: if not (staticVars(l[i].body, vars) and staticVars(l[i].orelse, vars)): return False elif type(l[i]) == ast.For: for var in vars: if var.id in allVariableNamesUsed(l[i].target): return False if not (staticVars(l[i].body, vars) and staticVars(l[i].orelse, vars)): return False elif type(l[i]) in [ast.FunctionDef, ast.ClassDef, ast.Try, ast.With]: log("transformations\tstaticVars\tMissing type: " + str(type(l[i])), "bug") # If a mutable variable is used, we can't trust it for var in mutableVars: if var.id in allVariableNamesUsed(l[i]): return False return True
def isStatement(a): """Determine whether the given node is a statement (vs an expression)""" return type(a) in [ ast.Module, ast.Interactive, ast.Expression, ast.Suite, ast.FunctionDef, ast.ClassDef, ast.Return, ast.Delete, ast.Assign, ast.AugAssign, ast.For, ast.While, ast.If, ast.With, ast.Raise, ast.Try, ast.Assert, ast.Import, ast.ImportFrom, ast.Global, ast.Expr, ast.Pass, ast.Break, ast.Continue ]
def applyVariableMap(a, variableMap): if not isinstance(a, ast.AST): return a if type(a) == ast.Name: if a.id in variableMap: a.id = variableMap[a.id] elif type(a) in [ast.FunctionDef, ast.ClassDef]: if a.name in variableMap: a.name = variableMap[a.name] return applyToChildren(a, lambda x : applyVariableMap(x, variableMap))
def class_check(node, kw=False): ''' Class specific check Action - check private method, move to utils check docstring scan for class - recursive class check scan for function - function check ''' status = True for child in ast.iter_child_nodes(node): if isinstance(child, ast.FunctionDef): if kw and child.name.startswith("_") and child.name != "__init__": print node.name, child.name, "should move to utils" status = False tmp_status = func_check(child, kw) status &= tmp_status elif isinstance(child, ast.ClassDef): tmp_status = class_check(child, kw) status &= tmp_status if ast.get_docstring(node) is None: # check for docstring print node.name, "doesn't contain any docstring" status = False return status
def visit_Call(self, node): _id = get_call_names_as_string(node.func) local_definitions = self.module_definitions_stack[-1] alias = handle_aliases_in_calls(_id, local_definitions.import_alias_mapping) if alias: definition = local_definitions.get_definition(alias) else: definition = local_definitions.get_definition(_id) # e.g. "request.args.get" -> "get" last_attribute = _id.rpartition('.')[-1] if definition: if isinstance(definition.node, ast.ClassDef): self.add_blackbox_or_builtin_call(node, blackbox=False) elif isinstance(definition.node, ast.FunctionDef): self.undecided = False self.function_return_stack.append(_id) return self.process_function(node, definition) else: raise Exception('Definition was neither FunctionDef or ' + 'ClassDef, cannot add the function ') elif last_attribute not in BUILTINS: # Mark the call as a blackbox because we don't have the definition return self.add_blackbox_or_builtin_call(node, blackbox=True) return self.add_blackbox_or_builtin_call(node, blackbox=False)
def get_vars(node): vv = VarsVisitor() if isinstance(node.ast_node, ast.While)\ or isinstance(node.ast_node, ast.If): vv.visit(node.ast_node.test) elif isinstance(node.ast_node, ast.FunctionDef) or\ isinstance(node.ast_node, ast.ClassDef): return list() else: try: vv.visit(node.ast_node) except AttributeError: # If no ast_node vv.result = list() # remove duplicates: vv.result = set(vv.result) # Filter out lvars: for var in vv.result: try: # if assignment node # print('r', node.right_hand_side_variables) # if var not in node.left_hand_side: if var in node.right_hand_side_variables: yield var except AttributeError: yield var
def top_level_classes(body): return (f for f in body if isinstance(f, ast.ClassDef))
def test_classes(self): matches = list(self.m.match('class', self.filepath('classes.py'))) self.assertEqual(len(matches), 4) # check instances self.assertIsInstance(matches[0][0], ast.ClassDef) self.assertIsInstance(matches[1][0], ast.ClassDef) self.assertIsInstance(matches[2][0], ast.ClassDef) self.assertIsInstance(matches[3][0], ast.ClassDef) # check lines self.assertEqual(matches[0][1], 1) self.assertEqual(matches[1][1], 9) self.assertEqual(matches[2][1], 13) self.assertEqual(matches[3][1], 14)
def match(self, selector, filename): module = astor.parsefile(filename) for match in super(ASTMatchEngine, self).match(selector, module.body): lineno = match.lineno if isinstance(match, (ast.ClassDef, ast.FunctionDef)): for d in match.decorator_list: lineno += 1 yield match, lineno
def pseudo_extends(matcher, node, value): if not isinstance(node, ast.ClassDef): return False if not value: return node.bases == [] bases = node.bases selectors = value.split(',') for selector in selectors: matches = matcher.match_data( matcher.parse_selector(selector)[0], bases) if any(matches): return True
def visit_ClassDef(self, node): # type: (ast.ClassDef) -> None # Not implemented yet. We want to ensure we don't # traverse into the class body for now. return
def top_level_classes(body): # return (node for node in ast.walk(body) if isinstance(node, ast.ClassDef)) return (f for f in body if isinstance(f, ast.ClassDef))
def visit_ClassDef(self, node, phase): '''Visitor for AST ClassDef node Add class name to current namespace for all descendants. :param node: Node being inspected :return: - ''' # For all child nodes, add this class name to current namespace self.namespace = b_utils.namespace_path_join(self.namespace, node.name)
def post_visit(self, node): self.depth -= 1 LOG.debug("%s\texiting : %s", self.depth, hex(id(node))) # HACK(tkelsey): this is needed to clean up post-recursion stuff that # gets setup in the visit methods for these node types. if isinstance(node, ast.FunctionDef) or isinstance(node, ast.ClassDef): self.namespace = b_utils.namespace_path_split(self.namespace)[0]
def check_size(example, size): tree = ast.parse(example) for node in tree.body: if isinstance(node, ast.ClassDef) and node.name == 'Foo': assert count_lines(node) == size break else: assert False, 'Failed to find top-level class "Foo" in code'
def parse_struct(node: ast.ClassDef) -> pysl.Struct: struct = pysl.Struct() struct.set_location(node) struct.name = node.name struct.elements = [] struct.set_location(node) for decl_node in node.body: if isinstance(decl_node, ast.AnnAssign): assignment = parse_assignment(decl_node) struct.elements.append((str_to_pysl_type(loc(node), assignment.type), assignment.name)) else: error(loc(decl_node), "Unrecognized node inside structure: {0}".format(struct.name)) return struct
def parse_stage_input(node: ast.ClassDef, stages: str) -> pysl.StageInput: si = pysl.StageInput() si.set_location(node) si.name = node.name si.elements = [] si.stages = stages conditions = [] for decl_node in node.body: if isinstance(decl_node, ast.AnnAssign): assignment = parse_assignment(decl_node) element = pysl.InputElement() element.set_location(decl_node) element.name = assignment.name element.type = str_to_pysl_type(loc(decl_node), assignment.type) element.semantic = assignment.value element.conditions = list(conditions) conditions[:] = [] # Copy si.elements.append(element) elif (isinstance(decl_node, ast.Expr) and isinstance(decl_node.value, ast.Call)): if decl_node.value.func.id is '_': conditions.append(parse_preprocessor(decl_node.value)) else: error(loc(decl_node), "Unsupported function call: {0} inside StageInput: {1}".format(decl_node.value.func.id, si.name)) else: error(loc(decl_node), "Unrecognized node inside StageInput: {0}".format(si.name)) si.post_conditions = list(conditions) return si
def parse_constant_buffer(node: ast.ClassDef) -> pysl.ConstantBuffer: cbuffer = pysl.ConstantBuffer() cbuffer.set_location(node) cbuffer.name = node.name cbuffer.constants = [] for decl_node in node.body: if isinstance(decl_node, ast.AnnAssign): assignment = parse_assignment(decl_node) constant = pysl.Constant() constant.set_location(decl_node) constant.name = assignment.name if assignment.value: try: constant.offset = int(assignment.value) except ValueError: error(loc(decl_node), "Expected numberic offset as argument") assignment.value constant.type = str_to_pysl_type(loc(decl_node), assignment.type) cbuffer.constants.append(constant) else: error(loc(decl_node), "Unrecognized node inside ConstantBuffer: {0}".format(cbuffer.name)) for d in node.decorator_list: decorator = parse_decorator(d) if decorator.args: try: cbuffer.enforced_size = int(decorator.args[0]) except ValueError: error(loc(d), "Expected integer argument to constructor indicating enforced size(in constants), but evaluated: {0}".format(decorator.args[0])) return cbuffer