我们从Python开源项目中,提取了以下50个代码示例,用于说明如何使用ast.Call()。
def _extract_scripts_from_project(setup_filename='setup.py'): """Parse setup.py and return scripts""" if not os.path.isfile(setup_filename): return '' mock_setup = textwrap.dedent('''\ def setup(*args, **kwargs): __setup_calls__.append((args, kwargs)) ''') parsed_mock_setup = ast.parse(mock_setup, filename=setup_filename) with open(setup_filename, 'rt') as setup_file: parsed = ast.parse(setup_file.read()) for index, node in enumerate(parsed.body[:]): if (not isinstance(node, ast.Expr) or not isinstance(node.value, ast.Call) or node.value.func.id != 'setup'): continue parsed.body[index:index] = parsed_mock_setup.body break fixed = ast.fix_missing_locations(parsed) codeobj = compile(fixed, setup_filename, 'exec') local_vars = {} global_vars = {'__setup_calls__': []} exec(codeobj, global_vars, local_vars) _, kwargs = global_vars['__setup_calls__'][0] return ','.join([os.path.basename(f) for f in kwargs.get('scripts', [])])
def __init__(self, stmt, context): self.stmt = stmt self.context = context self.stmt_table = { ast.Expr: self.expr, ast.Pass: self.parse_pass, ast.AnnAssign: self.ann_assign, ast.Assign: self.assign, ast.If: self.parse_if, ast.Call: self.call, ast.Assert: self.parse_assert, ast.For: self.parse_for, ast.AugAssign: self.aug_assign, ast.Break: self.parse_break, ast.Return: self.parse_return, } stmt_type = self.stmt.__class__ if stmt_type in self.stmt_table: self.lll_node = self.stmt_table[stmt_type]() elif isinstance(stmt, ast.Name) and stmt.id == "throw": self.lll_node = LLLnode.from_list(['assert', 0], typ=None, pos=getpos(stmt)) else: raise StructureException("Unsupported statement type", stmt)
def assign_tuple_target(self, node, right_hand_side_variables): new_assignment_nodes = list() for i, target in enumerate(node.targets[0].elts): value = node.value.elts[i] label = LabelVisitor() label.visit(target) if isinstance(value, ast.Call): new_ast_node = ast.Assign(target, value) new_ast_node.lineno = node.lineno new_assignment_nodes.append( self.assignment_call_node(label.result, new_ast_node)) else: label.result += ' = ' label.visit(value) new_assignment_nodes.append(self.append_node(AssignmentNode(label.result, self.extract_left_hand_side(target), ast.Assign(target, value), right_hand_side_variables, line_number = node.lineno, path=self.filenames[-1]))) self.connect_nodes(new_assignment_nodes) return ControlFlowNode(new_assignment_nodes[0], [new_assignment_nodes[-1]], []) # return the last added node
def visit_Assign(self, node): rhs_visitor = RHSVisitor() rhs_visitor.visit(node.value) if isinstance(node.targets[0], ast.Tuple): # x,y = [1,2] if isinstance(node.value, ast.Tuple): return self.assign_tuple_target(node, rhs_visitor.result) elif isinstance(node.value, ast.Call): call = None for element in node.targets[0].elts: label = LabelVisitor() label.visit(element) call = self.assignment_call_node(label.result, node) return call elif len(node.targets) > 1: # x = y = 3 return self.assign_multi_target(node, rhs_visitor.result) else: if isinstance(node.value, ast.Call): # x = call() label = LabelVisitor() label.visit(node.targets[0]) return self.assignment_call_node(label.result, node) else: # x = 4 label = LabelVisitor() label.visit(node) return self.append_node(AssignmentNode(label.result, self.extract_left_hand_side(node.targets[0]), node, rhs_visitor.result, line_number = node.lineno, path=self.filenames[-1]))
def visit_For(self, node): self.undecided = True # Used for handling functions in for loops #issue23 iterator_label = LabelVisitor() iterator = iterator_label.visit(node.iter) self.undecided = False target_label = LabelVisitor() target = target_label.visit(node.target) for_node = self.append_node(Node("for " + target_label.result + " in " + iterator_label.result + ':', node, line_number = node.lineno, path=self.filenames[-1])) if isinstance(node.iter, ast.Call) and get_call_names_as_string(node.iter.func) in self.function_names: last_node = self.visit(node.iter) last_node.connect(for_node) return self.loop_node_skeleton(for_node, node)
def add_function(self, call_node, definition): try: self.function_index += 1 def_node = definition.node saved_variables = self.save_local_scope(def_node.lineno) parameters = self.save_actual_parameters_in_temp(call_node.args, Arguments(def_node.args), call_node.lineno) self.filenames.append(definition.path) self.create_local_scope_from_actual_parameters(call_node.args, Arguments(def_node.args), def_node.lineno) function_nodes = self.get_function_nodes(definition) self.filenames.pop() # Maybe move after restore nodes restore_nodes = self.restore_saved_local_scope(saved_variables, parameters, def_node.lineno) self.return_handler(call_node, function_nodes, restore_nodes) self.function_return_stack.pop() except IndexError: error_call = get_call_names_as_string(call_node.func) print('Error: Possible nameclash in "{}". Call omitted!\n'.format(error_call)) return self.nodes[-1]
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 search(func, depth=1): local_vars = sys._getframe(depth).f_locals source = get_source_code(func) tree = ast.parse(source) child_funcs = [] for node in ast.walk(tree): if isinstance(node, ast.Call): if isinstance(node.func, ast.Name): child_funcs.append(node.func.id) elif (isinstance(node, ast.Name) and node.id in local_vars and callable(local_vars[node.id]) and node.id not in sys.builtin_module_names): child_funcs.append(node.id) child_load_str = '' for child in child_funcs: if child in local_vars: try: load_string = search(local_vars[child], depth=(depth + 1)) child_load_str += load_string + '\n' except Exception as e: pass load_str = child_load_str + source return load_str
def replaceHazards(a): if not isinstance(a, ast.AST): return for field in ast.walk(a): if type(a) == ast.Import: for i in range(len(a.names)): if a.names[i].name not in supportedLibraries: if not (a.names[i].name[0] == "r" and a.names[i].name[1] in "0123456789") and not ("NotAllowed" in a.names[i].name): a.names[i].name = a.names[i].name + "NotAllowed" elif type(a) == ast.ImportFrom: if a.module not in supportedLibraries: if not (a.module[0] == "r" and a.module[1] in "0123456789") and not ("NotAllowed" in a.module): a.module = a.module + "NotAllowed" elif type(a) == ast.Call: if type(a.func) == ast.Name and a.func.id in ["compile", "eval", "execfile", "file", "open", "__import__", "apply"]: a.func.id = a.func.id + "NotAllowed"
def findHelperFunction(a, helperId, helperCount): """Finds the first helper function used in the ast""" if not isinstance(a, ast.AST): return None # Check all the children, so that we don't end up with a recursive problem for child in ast.iter_child_nodes(a): f = findHelperFunction(child, helperId, helperCount) if f != None: return f # Then check if this is the right call if type(a) == ast.Call: if type(a.func) == ast.Name and a.func.id == helperId: if helperCount[0] > 0: helperCount[0] -= 1 else: return a return None
def cleanupRanges(a): """Remove any range shenanigans, because Python lets you include unneccessary values""" if not isinstance(a, ast.AST): return a if type(a) == ast.Call: if type(a.func) == ast.Name: if a.func.id in ["range"]: if len(a.args) == 3: # The step defaults to 1! if type(a.args[2]) == ast.Num and a.args[2].n == 1: a.args = a.args[:-1] if len(a.args) == 2: # The start defaults to 0! if type(a.args[0]) == ast.Num and a.args[0].n == 0: a.args = a.args[1:] return applyToChildren(a, cleanupRanges)
def cleanupSlices(a): """Remove any slice shenanigans, because Python lets you include unneccessary values""" if not isinstance(a, ast.AST): return a if type(a) == ast.Subscript: if type(a.slice) == ast.Slice: # Lower defaults to 0 if a.slice.lower != None and type(a.slice.lower) == ast.Num and a.slice.lower.n == 0: a.slice.lower = None # Upper defaults to len(value) if a.slice.upper != None and type(a.slice.upper) == ast.Call and \ type(a.slice.upper.func) == ast.Name and a.slice.upper.func.id == "len": if compareASTs(a.value, a.slice.upper.args[0], checkEquality=True) == 0: a.slice.upper = None # Step defaults to 1 if a.slice.step != None and type(a.slice.step) == ast.Num and a.slice.step.n == 1: a.slice.step = None return applyToChildren(a, cleanupSlices)
def process(fl, external, genfiles, vendor): src = open(fl).read() tree = ast.parse(src, fl) lst = [] wksp = WORKSPACE(external, genfiles, vendor) for stmt in ast.walk(tree): stmttype = type(stmt) if stmttype == ast.Call: fn = getattr(wksp, stmt.func.id, "") if not callable(fn): continue path, name = keywords(stmt) if path.endswith(".git"): path = path[:-4] path = pathmap.get(path, path) tup = fn(name, path) lst.append(tup) return lst
def return_handler(self, call_node, function_nodes, saved_function_call_index, first_node): """Handle the return from a function during a function call. Args: call_node(ast.Call) : The node that calls the definition. function_nodes(list[Node]): List of nodes of the function being called. saved_function_call_index(int): Unique number for each call. first_node(EntryOrExitNode or RestoreNode): Used to connect previous statements to this function. """ for node in function_nodes: # Only `Return`s and `Raise`s can be of type ConnectToExitNode if isinstance(node, ConnectToExitNode): # Create e.g. ¤call_1 = ret_func_foo RestoreNode LHS = CALL_IDENTIFIER + 'call_' + str(saved_function_call_index) RHS = 'ret_' + get_call_names_as_string(call_node.func) return_node = RestoreNode(LHS + ' = ' + RHS, LHS, [RHS], line_number=call_node.lineno, path=self.filenames[-1]) return_node.first_node = first_node self.nodes[-1].connect(return_node) self.nodes.append(return_node) return
def assign_tuple_target(self, node, right_hand_side_variables): new_assignment_nodes = list() for i, target in enumerate(node.targets[0].elts): value = node.value.elts[i] label = LabelVisitor() label.visit(target) if isinstance(value, ast.Call): new_ast_node = ast.Assign(target, value) new_ast_node.lineno = node.lineno new_assignment_nodes.append(self.assignment_call_node(label.result, new_ast_node)) else: label.result += ' = ' label.visit(value) new_assignment_nodes.append(self.append_node(AssignmentNode(label.result, self.extract_left_hand_side(target), ast.Assign(target, value), right_hand_side_variables, line_number=node.lineno, path=self.filenames[-1]))) self.connect_nodes(new_assignment_nodes) return ControlFlowNode(new_assignment_nodes[0], [new_assignment_nodes[-1]], []) # return the last added node
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_sink_args(cfg_node): if isinstance(cfg_node.ast_node, ast.Call): rhs_visitor = RHSVisitor() rhs_visitor.visit(cfg_node.ast_node) return rhs_visitor.result elif isinstance(cfg_node.ast_node, ast.Assign): return cfg_node.right_hand_side_variables vv = VarsVisitor() other_results = list() if isinstance(cfg_node, BBorBInode): other_results = cfg_node.args else: vv.visit(cfg_node.ast_node) return vv.result + other_results
def get_call_names_helper(node, result): """Recursively finds all function names.""" if isinstance(node, ast.Name): if node.id not in BLACK_LISTED_CALL_NAMES: result.append(node.id) return result elif isinstance(node, ast.Call): return result elif isinstance(node, ast.Subscript): return get_call_names_helper(node.value, result) elif isinstance(node, ast.Str): result.append(node.s) return result else: result.append(node.attr) return get_call_names_helper(node.value, result)
def test_call_arg_kwarg(self): matches1 = list(self.m.match('call[kwarg=a]', self.filepath('calls.py'))) matches2 = list(self.m.match('call[kwarg=x]', self.filepath('calls.py'))) matches3 = list(self.m.match('call[arg=bar]', self.filepath('calls.py'))) matches4 = list(self.m.match('[arg=bang]', self.filepath('calls.py'))) self.assertEqual(len(matches1), 1) self.assertEqual(len(matches2), 2) self.assertEqual(len(matches3), 2) self.assertEqual(len(matches4), 2) self.assertIsInstance(matches1[0][0], ast.Call) self.assertIsInstance(matches2[0][0], ast.Call) self.assertIsInstance(matches2[1][0], ast.Call) self.assertIsInstance(matches3[0][0], ast.Call) self.assertIsInstance(matches3[1][0], ast.Call) self.assertIsInstance(matches4[0][0], ast.Call)
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 _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 get_node_name_with_extra_code(self, node, extra_code): _ext_info = {'extra_code': extra_code} if isinstance(node, ast.Call): left_name = self.temp_variable.get_new_name() _temp = '%s\n' % self.dispatch(node, _ext_info) extra_code = '%s%s%s=$__return_%s\n' % ( _ext_info['extra_code'], _temp, left_name, node.func.id, ) left_name = '$%s' % left_name else: left_name = self.dispatch(node, _ext_info) extra_code = _ext_info['extra_code'] return left_name, extra_code
def generate_assign(self, node, ext_info): target_code = '' if isinstance(node.targets[0], ast.Name): target_code = self.dispatch(node.targets[0]) else: raise CompileError() if isinstance(node.value, ast.Call): return '%s\n%s=$__return_%s' % ( self.dispatch(node.value), target_code, node.value.func.id ) else: ext_info = {} value_code = self.dispatch(node.value, ext_info) extra_code = ext_info.get('extra_code', '') if value_code is None: raise CompileError() return extra_code + target_code + '=' + value_code
def generate_call(self, node, ext_info={}): if hasattr(node, 'kwargs'): if not node.kwargs is None: raise SyntaxNotSupportError('Keyword arguments is not support yet.') elif not len(node.keywords) == 0: raise SyntaxNotSupportError('Keyword arguments is not support yet.') function_name = node.func.id if len(node.args) is 0: return '%s' % function_name argument_list = [] if is_system_function(function_name): return self.generate_system_function(node, ext_info) for x in node.args: if isinstance(x, ast.Call): new_temp_variable = self.temp_variable.get_new_name() self.code_buffer.append(self.dispatch(x)) self.code_buffer.append('%s=$__return_%s' % (new_temp_variable, x.func.id)) argument_list.append(new_temp_variable) else: ext_info['is_arg'] = True argument_list.append(self.dispatch(x, ext_info=ext_info)) arguments_code = ' '.join(argument_list) return '%s %s' % (function_name, arguments_code)
def get_type(self, node): if isinstance(node, ast.Num): return Type.NUMBER elif isinstance(node, ast.Str): return Type.STRING elif isinstance(node, ast.Name): if self.variables[node.id] is not None: return self.variables[node.id].var_type else: return Type.VOID elif isinstance(node, ast.BinOp): if self.get_type(node.left).is_number and self.get_type(node.right).is_number: return Type.NUMBER elif self.get_type(node.left).is_string or self.get_type(node.right).is_string: return Type.STRING elif isinstance(node, ast.Call): return self.functions[node.func.id].return_type else: return Type.VOID
def requests_auth_literal(context): if re.match(r'requests\.(get|head|post|put|)', context.call_function_name_qual) is None: return call_node = context.node kwarg_nodes = dict((kwarg.arg, kwarg.value) for kwarg in call_node.keywords) if 'auth' not in kwarg_nodes: return auth_value = context.call_keywords.get('auth') if auth_value is not None: return bandit.Issue( severity=bandit.HIGH, confidence=(bandit.HIGH if (isinstance(auth_value, (list, tuple)) and len(auth_value) == 2) else bandit.MEDIUM), text="Hard-coded credentials are being passed to the requests library for basic authentication." ) if not isinstance(kwarg_nodes['auth'], ast.Call): return arg_call = b_utils.get_call_name(kwarg_nodes['auth'], context._context['import_aliases']) if arg_call not in ('requests.HTTPBasicAuth', 'requests.HTTPDigestAuth'): return parent = s_utils.get_top_parent_node(call_node) username = next(s_utils.get_call_arg_values(parent, kwarg_nodes['auth'], arg=0, child=call_node), None) password = next(s_utils.get_call_arg_values(parent, kwarg_nodes['auth'], arg=1, kwarg='password', child=call_node), None) return s_utils.report_hardcoded_credentials('requests', username, password)
def get_attribute_name(node, import_aliases=None): import_aliases = import_aliases or {} if not isinstance(node, ast.Attribute): raise ValueError('node must be an instance of ast.Attribute') base = node.attr name = '' node = node.value while isinstance(node, ast.Attribute): name = node.attr + '.' + name node = node.value if isinstance(node, (ast.Call, ast.Subscript)): return None if not isinstance(node, ast.Name): raise ValueError('could not resolve node for attribute') name = (node.id + '.' + name)[:-1] return import_aliases.get(name, name) + '.' + base
def get_call_arg_values(parent, call_node, arg=None, kwarg=None, child=None): """Only returns literals.""" if not isinstance(call_node, ast.Call): raise ValueError('call_node must be an ast.Call instance') if arg is None and kwarg is None: raise RuntimeError('either an arg or kwarg must be specified') arg_node = None if arg is not None: if not isinstance(arg, int): raise ValueError('arg must be specified as a 0-indexed argument position') if arg < len(call_node.args): arg_node = call_node.args[arg] if arg_node is None and kwarg is not None: if not isinstance(kwarg, str): raise ValueError('kwarg must be specified as the string of a keyword argument name') arg_node = next((kw.value for kw in call_node.keywords if kw.arg == kwarg), None) if arg_node is None: return if not hasattr(arg_node, 'parent'): arg_node.parent = call_node for arg_value in iter_expr_literal_values(parent, arg_node, child=child): yield arg_value
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 _solve(self): import_aliases = (self.context._context['import_aliases'] if self.context else None) cursor_node = self.tainted_node.parent while cursor_node != self.target_node: test_node = cursor_node cursor_node = cursor_node.parent if isinstance(test_node, ast.BinOp): continue elif isinstance(test_node, ast.Call): if isinstance(test_node.func, ast.Attribute) and isinstance(test_node.func.value, ast.Str) and test_node.func.attr == 'format': return True function = s_utils.get_call_function(test_node, import_aliases=import_aliases) if function in ('os.path.abspath', 'os.path.join', 'str'): continue elif function == 'os.path.relpath' and s_utils.node_is_child_of_parent(test_node.args[0], self.tainted_node): continue elif isinstance(test_node, ast.Subscript): continue return False return True
def test_dump(self): node = ast.parse('spam(eggs, "and cheese")') self.assertEqual(ast.dump(node), "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load()), " "args=[Name(id='eggs', ctx=Load()), Str(s='and cheese')], " "keywords=[], starargs=None, kwargs=None))])" ) self.assertEqual(ast.dump(node, annotate_fields=False), "Module([Expr(Call(Name('spam', Load()), [Name('eggs', Load()), " "Str('and cheese')], [], None, None))])" ) self.assertEqual(ast.dump(node, include_attributes=True), "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load(), " "lineno=1, col_offset=0), args=[Name(id='eggs', ctx=Load(), " "lineno=1, col_offset=5), Str(s='and cheese', lineno=1, " "col_offset=11)], keywords=[], starargs=None, kwargs=None, " "lineno=1, col_offset=0), lineno=1, col_offset=0)])" )
def test_call(self): func = ast.Name("x", ast.Load()) args = [ast.Name("y", ast.Load())] keywords = [ast.keyword("w", ast.Name("z", ast.Load()))] stararg = ast.Name("p", ast.Load()) kwarg = ast.Name("q", ast.Load()) call = ast.Call(ast.Name("x", ast.Store()), args, keywords, stararg, kwarg) self.expr(call, "must have Load context") call = ast.Call(func, [None], keywords, stararg, kwarg) self.expr(call, "None disallowed") bad_keywords = [ast.keyword("w", ast.Name("z", ast.Store()))] call = ast.Call(func, args, bad_keywords, stararg, kwarg) self.expr(call, "must have Load context") call = ast.Call(func, args, keywords, ast.Name("z", ast.Store()), kwarg) self.expr(call, "must have Load context") call = ast.Call(func, args, keywords, stararg, ast.Name("w", ast.Store())) self.expr(call, "must have Load context")
def _get_ast_name_node(node): while True: # only accept '*var' if isinstance(node, ast.Starred): # '*var = value' => 'var' node = node.value elif isinstance(node, ast.Subscript): # 'obj[slice] = value' => 'obj' node = node.value elif isinstance(node, ast.Attribute): # 'obj.attr = value' => 'obj' node = node.value elif (isinstance(node, ast.Call) and isinstance(node.func, ast.Attribute)): # 'obj.method().attr = value' => 'obj.method' node = node.func else: return node
def NAME(self, node): """ Handle occurrence of Name (which can be a load/store/delete access.) """ # Locate the name in locals / function / globals scopes. if isinstance(node.ctx, (ast.Load, ast.AugLoad)): self.handleNodeLoad(node) if (node.id == 'locals' and isinstance(self.scope, FunctionScope) and isinstance(node.parent, ast.Call)): # we are doing locals() call in current scope self.scope.usesLocals = True elif isinstance(node.ctx, (ast.Store, ast.AugStore)): self.handleNodeStore(node) elif isinstance(node.ctx, ast.Del): self.handleNodeDelete(node) else: # must be a Param context -- this only happens for names in function # arguments, but these aren't dispatched through here raise RuntimeError("Got impossible expression context: %r" % (node.ctx,))
def parse_decorator(node: ast.AST): if isinstance(node, ast.Name): ret = Decorator() ret.name = node.id return ret elif isinstance(node, ast.Call): ret = Decorator() ret.name = node.func.id for arg in node.args: if isinstance(arg, ast.Num): ret.args.append(str(arg.n)) elif isinstance(arg, ast.Str): ret.args.append(str(arg.n)) elif isinstance(arg, ast.Name): ret.args.append(arg.id) else: v = eval_numeric_constexpr(arg) if v: ret.args.append(str(v)) else: error(loc(node), "Unsupported decorator type") return ret else: error(loc(node), "Supported decorators are Name and Call") return None
def parse_for_range(node: ast.Call) -> (str, str, str): if len(node.args) != 3: error(loc(node), "Expected 3 integer arguments in range(start, end, stop) found: {0}".format(len(node.args))) return ('ERR', 'ERR', 'ERR') if isinstance(node.args[0], ast.Name): ok1, v1 = True, node.args[0].id else: ok1, v1 = TO_INT(node.args[0]) if isinstance(node.args[1], ast.Name): ok2, v2 = True, node.args[1].id else: ok2, v2 = TO_INT(node.args[1]) if isinstance(node.args[2], ast.Name): ok3, v3 = True, node.args[2].id else: ok3, v3 = TO_INT(node.args[2]) if ok1 and ok2 and ok3: return (str(v1), str(v2), str(v3)) return ('ERR', 'ERR', 'ERR')
def PYSL_tl_decl(node: ast.AnnAssign): """Parses a specific top-level declaration""" if not isinstance(node.annotation, ast.Call) or (node.annotation.func.id != 'register' or len(node.annotation.args) != 2 or not isinstance(node.annotation.args[0], ast.Name) or not isinstance(node.annotation.args[1], ast.Num)): error(loc(node), "Invalid top level resource declaration, see docs. <name> : register(<type>, <slot>) = (...)") res_name = node.target.id res_type = node.annotation.args[0].id res_slot = node.annotation.args[1].n if res_type in pysl.Language.Sampler.TYPES: emitter.sampler(parse_sampler(node, res_name, res_type[7:], res_slot, node.value)) else: error((node), "Unrecognized top-level resource declaration {0} : {1}".format(res_name, res_type))
def _Call(self, t): if isinstance(t, ast.Call): super()._Call(t) return self.dispatch(t.func) self.write("(") comma = False for e in t.args: if comma: self.write(", ") else: comma = True self.dispatch(e) for e in t.keywords: if comma: self.write(", ") else: comma = True self.dispatch(e) self.write(")")
def parse_factor_expression(call_or_name_node): if isinstance(call_or_name_node, ast.Name): # a.set_to(b) is shorthand for a.set_to(Copy(b)) name_node = call_or_name_node return None, [name_node.id] elif isinstance(call_or_name_node, ast.Call): # a.set_to(f(b)) call_node = call_or_name_node return call_node.func.id, [name_or_number(node) for node in call_node.args] elif isinstance(call_or_name_node, ast.Num): # a.observe_value(0) num_node = call_or_name_node return None, [int(num_node.n)] elif isinstance(call_or_name_node, ast.Subscript): print ast.dump(call_or_name_node) pdb.set_trace() else: assert False, "Can't parse factor " + ast.dump(call_or_name_node)
def parse(self, assign_node): if len(assign_node.targets) > 1: return False if u.is_constant_definition(assign_node): return None self.name = assign_node.targets[0].id rhs = assign_node.value if isinstance(rhs, ast.Call): call_node = u.cast(rhs, ast.Call) self.parse_call(call_node) self.array_size = None elif isinstance(rhs, ast.Subscript): subscript_node = u.cast(rhs, ast.Subscript) call_node = u.cast(subscript_node.value, ast.Call) self.parse_call(call_node) self.array_size = u.get_index(subscript_node)
def visit_For(self, forstmt): s = "" if isinstance(forstmt.iter, ast.Call) \ and isinstance(forstmt.iter.func, ast.Name) \ and forstmt.iter.func.id == "range": iter_var = self.visit(forstmt.target) if len(forstmt.iter.args) == 1: iter_len = self.visit(forstmt.iter.args[0]) s += "for (int %s = 0; %s < %s; %s++) {\n" % (iter_var, iter_var, iter_len, iter_var) else: iter_start = self.visit(forstmt.iter.args[0]) iter_len = self.visit(forstmt.iter.args[1]) s += "for (int %s = %s; %s < %s; %s++) {\n" % (iter_var, iter_start, iter_var, iter_len, iter_var) s += self.visit_block(forstmt.body) s += "}\n" return s else: raise "only for var in range(a) loops supported currently"
def check_reshape(node): if not isinstance(node, ast.Call): return if not isinstance(node.func, ast.Attribute): return if isinstance(node.func.value, ast.Name) and \ node.func.value.id in {'np', 'cupy', 'F'}: return if not node.func.attr == 'reshape': return if len(node.args) > 1: yield (node.lineno, 'reshape(A, B, ...)') if len(node.args) == 1 and \ isinstance(node.args[0], ast.Tuple) and \ len(node.args[0].elts) == 1: yield (node.lineno, 'reshape((A,))')
def check_transpose(node): if not isinstance(node, ast.Call): return if not isinstance(node.func, ast.Attribute): return if isinstance(node.func.value, ast.Name) and \ node.func.value.id in {'np', 'cupy', 'F'}: return if not node.func.attr == 'transpose': return if len(node.args) > 1: yield (node.lineno, 'transpose(A, B, ...)') if len(node.args) == 1 and \ isinstance(node.args[0], ast.Tuple) and \ len(node.args[0].elts) == 1: yield (node.lineno, 'transpose((A,))')
def Call(fn, args): return ast.Call(fn, args, [], None, None)
def visit_Assert(self, t): return ast.If(t.test, [], [ast.Raise(Call(ast.Name('AssertionError', load), [] if t.msg is None else [t.msg]), None)])
def visit_FunctionDef(self, t): fn = Function(t.name, t.args, t.body) for d in reversed(t.decorator_list): fn = Call(d, [fn]) return ast.Assign([ast.Name(t.name, store)], fn)
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_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_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)