def _fill_in_default_arguments(func: Callable, call: ast.Call) -> Tuple[ast.Call, Type]: """Given a call and the function definition: * Defaults are filled in * A keyword argument that is positional is moved to the end * A follower is left to the original to help with recovering modifications to nested expressions. # TODO: Use python's signature bind to do this: # https://docs.python.org/3/library/inspect.html#inspect.Signature.bind) Args: func (Callable): The function definition call (ast.Call): The ast call site to be modified Raises: ValueError: Missing arguments, etc. Returns: Tuple[ast.Call, Type]: The modified call site and return type. """ sig = inspect.signature(func) i_arg = 0 arg_array = list(call.args) keywords = list(call.keywords) for param in sig.parameters.values(): if param.name != "self": if len(arg_array) <= i_arg: # See if they specified it as a keyword a, keywords = _find_keyword(keywords, param.name) if a is not None: arg_array.append(a) # type: ignore elif param.default is not param.empty: a = as_literal(param.default) arg_array.append(a) else: raise ValueError(f"Argument {param.name} is required") # If we are making a change to the call, put in a reference back to the # original call. if len(arg_array) != len(call.args): old_call_ast = call call = copy.copy(call) call.args = arg_array call.keywords = keywords call._old_ast = old_call_ast # type: ignore # Mark the return type - especially if it is missing t_info = get_type_hints(func) return_type = Any if "return" in t_info: return_type = t_info["return"] else: logging.getLogger(__name__).warning( f"Missing return annotation for {func.__name__}" " - assuming Any") return_type = Any return call, return_type
def make_node(filename, node, name, values=[]): return copy_loc( node, Call( func=copy_loc(node, from_w("W" + name[0].upper() + name[1:])), args=list(values), keywords=[ keyword( arg="src_pos", value=copy_loc( node, Call( func=copy_loc(node, from_w("SrcPos")), args=list( map( Constant, [ node.lineno, node.col_offset, node.end_lineno, node.end_col_offset, filename, ], ) ), keywords=[], ), ), ) ], ), )
def visit_Call(self, node): existing_node = self.generic_visit(node) value_node = existing_node.func if isinstance(value_node, Name) and value_node.id == 'print': return self._trace_print_function(existing_node) names = self._get_attribute_names(value_node) if names is None: return existing_node args = [ Str(s='.'.join(names[:-1])), Call(func=Name(id='repr', ctx=Load()), args=[existing_node.func.value], keywords=[], starargs=None, kwargs=None), existing_node, Call(func=Name(id='repr', ctx=Load()), args=[existing_node.func.value], keywords=[], starargs=None, kwargs=None), Num(n=existing_node.lineno) ] new_node = self._create_bare_context_call('record_call', args) return new_node
def validate_callable_arguments(self, call: ast.Call, callable_target: Callable) -> bool: if (callable_target.allow_starred_argument and not hasattr(call, 'checked_starred_args') and len(call.args) > len(callable_target.args_without_default)): args = self.parse_to_node(str(Type.sequence.default_value), call) args.elts = call.args call.args = [args] call.checked_starred_args = True len_call_args = len(call.args) callable_required_args = len(callable_target.args_without_default) if len_call_args > len(callable_target.args): unexpected_arg = call.args[len(callable_target.args)] self._log_error( CompilerError.UnexpectedArgument(unexpected_arg.lineno, unexpected_arg.col_offset) ) return False elif len_call_args < callable_required_args: missed_arg = list(callable_target.args)[len(call.args)] self._log_error( CompilerError.UnfilledArgument(call.lineno, call.col_offset, missed_arg) ) return False if isinstance(callable_target, IBuiltinMethod) and callable_target.requires_reordering: if not hasattr(call, 'was_reordered') or not call.was_reordered: callable_target.reorder(call.args) call.was_reordered = True if callable_required_args <= len_call_args < len(callable_target.args): included_args = len_call_args - callable_required_args call.args.extend(callable_target.defaults[included_args:]) return True
def parameter_ast( cls, type_defs: TypesDict, scene: CScene, project: CProject, action_id: str, parameter_id: str ) -> Call: val = cls.parameter_value(type_defs, scene, project, action_id, parameter_id) return Call( func=Name(id=RelativePose.__name__, ctx=Load()), args=[ Call( func=Name(id=Position.__name__, ctx=Load()), args=[ Num(n=val.position.x, kind=None), Num(n=val.position.y, kind=None), Num(n=val.position.z, kind=None), ], keywords=[], ), Call( func=Name(id=Orientation.__name__, ctx=Load()), args=[ Num(n=val.orientation.x, kind=None), Num(n=val.orientation.y, kind=None), Num(n=val.orientation.z, kind=None), Num(n=val.orientation.w, kind=None), ], keywords=[], ), ], keywords=[], )
def getLambdaMethod(methodname, body, args_node, file, id): # methodname = _lambda_0 global lambdaID fullbody = [] fullbody.extend(getTracers(file, args_node, id)) fullbody.append(getScopeTracer(file, methodname, id)) fullbody.append( Return( value=Call( func=Name(id='eval', ctx=Load()), args=[ Constant(value=to_source(body), kind=None), Call( func=Name(id='locals', ctx=Load()), args=[], keywords=[]), Name(id=methodname + '_locals', ctx=Load())], keywords=[] ) ) ) return FunctionDef( name=methodname + '_return', args=args_node, body=fullbody, decorator_list=[], returns=None, type_comment=None)
def visit_Call(self, node: Call): if _is_operation_call(node): node.func = copy_location(_wrap_in_controlled(node.func), node) node.args.insert( 0, copy_location(Name(self._control_param_name, ctx=Load()), node.args[0])) return node if _is_variant_call(node): functor_application = node.func if _identify_signature(functor_application) == 'Id': node.func = copy_location(_wrap_in_controlled(node.func), node) node.args.insert( 0, copy_location(Name(self._control_param_name, ctx=Load()), node.args[0])) else: node.args[0] = copy_location( _extend_control_data(node.args[0], self._control_param_name), node.args[0]) self.generic_visit(node) return node
class ImportBombast(RenameBombast): # import sys -> sys = __import__('sys', globals(), locals(), [], 0) one = Transformation(lambda n: Assign( targets=[Name(id=n.names[0].name, ctx=Store())], value=Call(func=Name(id='__import__', ctx=Load()), args=[ Str(s=n.names[0].name), Call(func=Name(id='globals', ctx=Load()), args=[], keywords=[], starargs=None, kwargs=None), Call(func=Name(id='locals', ctx=Load()), args=[], keywords=[], starargs=None, kwargs=None), List(elts=[], ctx=Load()), Num(n=0) ], keywords=[], starargs=None, kwargs=None))) def transform(self): num_imports = len(self.node.names) if num_imports == 1: return self.one.transform(self.node) else: return self.node
def handle_q(self, q): if not q.children: expr = Name(id="True", **self.file) elif len(q.children) == 1: expr = self._attr_lookup(*q.children[0]) elif q.connector == "AND": expr = Call( func=Name(id="all", **self.file), args=[ List(elts=[self._attr_lookup(k, v) for k, v in q.children], **self.file) ], keywords=[], kwonlyargs=[], **self.file, ) else: # q.connector == 'OR' expr = Call( func=Name(id="any", **self.file), args=[ List(elts=[self._attr_lookup(k, v) for k, v in q.children], **self.file) ], keywords=[], kwonlyargs=[], **self.file, ) if q.negated: return UnaryOp(op=Not(), operand=expr, **self.file) return expr
def visit_FunctionDef(self, node): writer.write('def %s(args, kwargs):' % node.name) writer.push() # new pythonjs' python function arguments handling # create the structure representing the functions arguments # first create the defaultkwargs JSObject writer.write('var(signature, arguments)') L = len(node.args.defaults) kwargsdefault = map(lambda x: keyword(self.visit(x[0]), x[1]), zip(node.args.args[-L:], node.args.defaults)) kwargsdefault = Call(Name('JSObject', None), [], kwargsdefault, None, None) args = Call(Name('JSArray', None), map(lambda x: Str(x.id), node.args.args), [], None, None) keywords = list([ keyword(Name('kwargs', None), kwargsdefault), keyword(Name('args', None), args), ]) if node.args.vararg: keywords.append( keyword(Name('vararg', None), Str(node.args.vararg))) if node.args.kwarg: keywords.append( keyword(Name('varkwarg', None), Str(node.args.kwarg))) prebody = list() # create a JS Object to store the value of each parameter signature = ', '.join( map(lambda x: '%s=%s' % (self.visit(x.arg), self.visit(x.value)), keywords)) writer.write('signature = JSObject(%s)' % signature) writer.write('arguments = get_arguments(signature, args, kwargs)') # # then for each argument assign its value for arg in node.args.args: writer.write("""JS("var %s = arguments['%s']")""" % (arg.id, arg.id)) if node.args.vararg: writer.write("""JS("var %s arguments['%s']")""" % (node.args.vararg, node.args.vararg)) # turn it into a list expr = '%s = get_attribute(list, "__call__")(create_array(%s), {});' expr = expr % (node.args.vararg, node.args.vararg) writer.write(expr) if node.args.kwarg: writer.write("""JS('var %s = arguments["%s"]')""" % (node.args.kwarg, node.args.kwarg)) expr = '%s = get_attribute(dict, "__call__")(create_array(%s), {});' expr = expr % (node.args.kwarg, node.args.kwarg) writer.write(expr) map(self.visit, node.body) writer.pull() # apply decorators for decorator in reversed(node.decorator_list): writer.write('%s = %s(create_array(%s))' % (node.name, self.visit(decorator), node.name))
def visit_BinOp(self, node): if node.op is Pow: return Call( Attribute( Call(Name('getcontext', Load()), [], [], None, None), 'power', Load()), [node.left, node.right], [], None, None) return node
def visit_Num(self, node): if isinstance(node.n, int): return fix_missing_locations( Call(func=Name('Integer', Load()), args=[node], keywords=[])) elif isinstance(node.n, float): return fix_missing_locations( Call(func=Name('Float', Load()), args=[node], keywords=[])) return node
def visit_Num(self, node): if isinstance(node.n, int): return fix_missing_locations( Call(Name('Integer', Load()), [node], [], None, None)) elif isinstance(node.n, float): return fix_missing_locations( Call(Name('Real', Load()), [node], [], None, None)) return node
def visit_Call(self, node: ast.Call) -> ast.Call: self.found = False self.generic_visit(node) if self.found: node.args = [self.do_placeholder(x) for x in node.args] node.keywords = [(arg, self.do_placeholder(value)) for arg, value in node.keywords] return node
def visit_Subscript(self, node): from ast import Expr, Call, Name, Load, Lambda, arguments, arg m = match("E[ _expr | _x in _set]", node) if m: x_s = m["_x"].id # name of dummy vaqriable expr = m["_expr"] sset = m["_set"] res = Call( func=Name(id="Ex", ctx=Load()), args=[ Lambda( args=arguments( args=[arg(arg=x_s, annotation=None)], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[], ), body=expr, ), sset, ], keywords=[], starargs=None, kwargs=None, ) return res m = match("Sum[ _expr | _x in _set]", node) if m: x_s = m["_x"].id # name of dummy vaqriable expr = m["_expr"] sset = m["_set"] res = Call( func=Name(id="Sum", ctx=Load()), args=[ Lambda( args=arguments( args=[arg(arg=x_s, annotation=None)], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[], ), body=expr, ), sset, ], keywords=[], starargs=None, kwargs=None, ) return res return node
def visit_FunctionDef(self, node): """ Instrument a function definition by creating a new report builder for this stack frame and putting it in a local variable. The local variable has the same name as the global variable so all calls can use the same CONTEXT_NAME symbol, but it means that I had to use this: x = globals()['x'].start_frame() Kind of ugly, but I think it was worth it to handle recursive calls. """ if node.name == '__repr__': return node new_node = self.generic_visit(node) line_numbers = set() self._find_line_numbers(new_node, line_numbers) first_line_number = min(line_numbers) last_line_number = max(line_numbers) args = [Num(n=first_line_number), Num(n=last_line_number)] try_body = new_node.body globals_call = Call(func=Name(id='globals', ctx=Load()), args=[], keywords=[], starargs=None, kwargs=None) global_context = Subscript(value=globals_call, slice=Index(value=Str(s=CONTEXT_NAME)), ctx=Load()) start_frame_call = Call(func=Attribute(value=global_context, attr='start_frame', ctx=Load()), args=args, keywords=[], starargs=None, kwargs=None) context_assign = Assign(targets=[Name(id=CONTEXT_NAME, ctx=Store())], value=start_frame_call) new_node.body = [context_assign] # trace function parameter values for target in new_node.args.args: if isinstance(target, Name) and target.id == 'self': continue if arg and isinstance(target, arg) and target.arg == 'self': continue new_node.body.append(self._trace_assignment(target, node.lineno)) handler_body = [self._create_context_call('exception'), Raise()] new_node.body.append( TryExcept(body=try_body, handlers=[ExceptHandler(body=handler_body)], orelse=[], finalbody=[])) self._set_statement_line_numbers(try_body, first_line_number) self._set_statement_line_numbers(handler_body, last_line_number) return new_node
def visit_Num(self, node): """This function exists for backwards compatibility with Python 3.7. It should be removed when SymPy removes support for Python 3.7.""" if isinstance(node.n, int): return fix_missing_locations( Call(func=Name('Integer', Load()), args=[node], keywords=[])) elif isinstance(node.n, float): return fix_missing_locations( Call(func=Name('Float', Load()), args=[node], keywords=[])) return node
def visit_Await(self, node): self.generic_visit(node) new = Call(func=Attribute(value=Call(func=Attribute( value=Name(id='_asyncio', ctx=Load()), attr='get_event_loop', ctx=Load()), args=[], keywords=[]), attr='run_until_complete', ctx=Load()), args=[node.value], keywords=[]) return ast.copy_location(new, node)
def visit_Expr(self, node: Expr) -> Expr: node.value = Call(func=Name(id='__autoexpr__', ctx=Load()), args=[node.value], keywords=[]) fix_missing_locations(node) return node
def visit_call_Aggregate_initial(self, node: ast.Call): ''' - (const, acc lambda): the accumulator is set to the value, and then the lambda is called to update it on every single element. This is called `agg_initial` ''' agg_lambda = node.args[1] init_val = self.get_rep(node.args[0]) # Get the sequence we are calling against and the accumulator seq = self.as_sequence(node.func.value) accumulator, accumulator_scope = self.create_accumulator( seq, initial_value=init_val, acc_type=init_val.cpp_type()) # Now do the accumulation. This happens at the current iterator scope. sv = seq.sequence_value() if isinstance(sv, crep.cpp_sequence): self._gc.set_scope(sv.iterator_value().scope()[-1]) else: self._gc.set_scope(sv.scope()) call = ast.Call( func=agg_lambda, args=[accumulator.as_ast(), seq.sequence_value().as_ast()]) self._gc.add_statement( statement.set_var(accumulator, self.get_rep(call))) # Finally, since this is a terminal, we need to pop off the top. self._gc.set_scope(accumulator_scope) # Cache the results in our result in case we are skipping nodes in the AST. node.rep = accumulator self._result = accumulator
def visit_Lambda(self, node): args = [self.visit(arg) for arg in node.args.args] body = self.visit(node.body) n = Call(func=Name('Lambda', Load()), args=[Tuple(args, Load()), body], keywords=[]) return fix_missing_locations(n)
def visitblock(self,body,kind): if not self.enableCodeCoverage: return if self.hot == None: return for i in reversed(range(len(body)+1)): versneaky0 = Expr(value=Call(func=Attribute(value=Name(id='madscience_debug_context', ctx=Load()), attr='log', ctx=Load()), args=[Num(n=self.scopes[self.hot]+i)], keywords=[])) body.insert(i,versneaky0) self.scopes[self.hot]+=len(body)
def visit_Call(self, node): name = node.func.id args = node.args[0] if name in self.variables: if isinstance(args, UnaryOp): # we have s(+1) if (isinstance(args.op, UAdd)): args = args.operand date = args.n elif (isinstance(args.op, USub)): args = args.operand date = -args.n else: raise Exception("Unrecognized subscript.") else: date = args.n if self.shift == 'S': return ast.parse('{}'.format(name)).body[0].value else: new_date = date + self.shift if new_date != 0: return ast.parse('{}({})'.format(name, new_date)).body[0].value else: return ast.parse('{}'.format(name)).body[0].value else: # , keywords=node.keywords, kwargs=node.kwargs) return Call(func=node.func, args=[self.visit(e) for e in node.args], keywords=[])
def visit_Call(self, node): name = node.func.id args = node.args[0] if name in self.variables: if isinstance(args, UnaryOp): # we have s(+1) if (isinstance(args.op, UAdd)): args = args.operand date = args.n elif (isinstance(args.op, USub)): args = args.operand date = -args.n else: raise Exception("Unrecognized subscript.") else: date = args.n newname = std_tsymbol((name, date)) if newname is not None: return Name(newname, Load()) else: # , keywords=node.keywords, starargs=node.starargs, kwargs=node.kwargs) return Call(func=node.func, args=[self.visit(e) for e in node.args], keywords=[])
def _wrap(self, fname, node): ''' Convert `node` into `fname(node)` ''' return copy_location( Call(func=Name(id=fname, ctx=Load()), args=[node], keywords=[]), node)
def _expand(self, syntax, target, macroname, tree, kw=None): """ Transform `target` node, replacing it with the expansion result of aplying the named macro on the proper node and recursively treat the expansion as well. """ macro = self.bindings[macroname] kw = kw or {} kw.update({ 'syntax': syntax, 'to_source': unparse, 'expand_macros': self.visit }) expansion = _apply_macro(macro, tree, kw) if syntax == 'block': # I'm not sure why is all this mess # # Strategy 1: Make the last line cover the whole block. # Result: Covers the "with document" line, but not the last one. # copy_location(expansion[-1], target) # # Strategy 2: Make the second line cover the whole block. # Result: Covers all, unless the block is just 2 lines. # copy_location(expansion[1], target) # Lo mejor para largo > 2 # # Strategy 3: Insert a second dummy line covering the whole block. # Result: Works dummy = Expr(value=Call(func=Name(id="id", ctx=Load()), args=[Constant(value="bogus", kind=None)], keywords=[]), lineno=target.lineno) copy_location(dummy, target) expansion.insert(1, dummy) expansion = self._visit_expansion(expansion, target) return expansion
def _convert_newtype_args(self, node: ast3.Call): if len(node.args) != 2: msg = "Wrong args: expected NewType(name, [(field, type), ...])" raise ParseError(msg) name, typ = node.args typ = self.convert_node(typ) node.args = [name.s, typ]
def visit_Call(self, node): name = node.func.id args = node.args[0] if name in self.variables: if isinstance(args, UnaryOp): # we have s(+1) if (isinstance(args.op, UAdd)): args = args.operand date = args.n elif (isinstance(args.op, USub)): args = args.operand date = -args.n else: raise Exception("Unrecognized subscript.") else: date = args.n key = (name, date) newname = self.table_symbols.get(key) if newname is not None: return Name(newname, Load()) else: raise Exception( "Symbol {} incorrectly subscripted with date {}.".format(name, date)) else: # , keywords=node.keywords, kwargs=node.kwargs) return Call(func=node.func, args=[self.visit(e) for e in node.args], keywords=[])
def make_function(name, args): my_args = arguments( args=[arg(arg="self", annotation=None)] + [ # XXX for arrays the name is '' (empty string) # which would end up being nothing in the generated # source file. arg(arg=my_arg or "arg", annotation=None) for my_arg in args ], defaults=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, ) my_body = [ Return(value=Call( func=Attribute( value=Attribute( value=Attribute(value=Name(id="self"), attr="_contract"), attr="functions", ), attr=name, ), args=[Name(id=my_arg or "arg") for my_arg in args], keywords=[], )) ] return FunctionDef(name=name, args=my_args, body=my_body, decorator_list=[])
def visit_Call(self, node: ast.Call) -> Any: try: global_func = astutils.evalnode(node.func, self.globals) if self.resolve_functions: global_val = astutils.evalnode(node, self.globals) else: global_val = node except SyntaxError: return self.generic_visit(node) newnode = None if self.resolve_functions and global_val is not node: # Without this check, casts don't generate code if not isinstance(global_val, dtypes.typeclass): newnode = self.global_value_to_node( global_val, parent_node=node, qualname=astutils.unparse(node), recurse=True) if newnode is not None: return newnode elif not isinstance(global_func, dtypes.typeclass): callables = not self.do_not_detect_callables newnode = self.global_value_to_node( global_func, parent_node=node, qualname=astutils.unparse(node), recurse=True, detect_callables=callables) if newnode is not None: node.func = newnode return self.generic_visit(node) return self.generic_visit(node)