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 _attr_lookup(self, attr, value): if "__" not in attr: return Compare( left=Attribute(value=Name(id="self", **self.file), attr=attr, **self.file), ops=[Eq()], comparators=[self.build_expression(value)], **self.file, ) attr, lookup = attr.split("__", 1) if lookup == "isnull": return Compare( left=Attribute(value=Name(id="self", **self.file), attr=attr, **self.file), ops=[Is() if value else IsNot()], comparators=[ Constant(value=None, **self.file) # Name(id="None", **self.file) ], **self.file, ) if lookup == "exact": return self._attr_lookup(attr, value) raise ValueError("Unhandled attr lookup")
def visit_Module(self, node): logging.info("Adding " + str(len(self.globalvars)) + " global variables, " + str(len(self.methods)) + " methods") node_body = node.body node.body = [] for n in node_body: if type(n) is ast.ImportFrom or type(n) is ast.Import: node.body.append(n) node_body.remove(n) node.body.append( Import(names=[alias(name='sys', asname=None)]) ) node.body.append(Expr(value=Call(func=Attribute( value=Attribute(value=Name(id='sys', ctx=Load()), attr='path', ctx=Load()), attr='append', ctx=Load()), args=[Constant(value=path_to_tracer, kind=None)], keywords=[])) ) node.body.append(Import(names=[alias(name='Tracer', asname=None)])) for globalvar in self.globalvars: node.body.append(globalvar) for method in self.methods: node.body.append(method) node.body.extend(node_body) return node
def _if_pattern(self, pattern): self.imported.add('re') # fix known ietf regex use pattern = pattern.replace('\\p{N}\\p{L}', '\\w') return [ If( test=UnaryOp( op=Not(), operand=Call( func=Attribute( value=Name(id='re', ctx=Load()), attr='match', ctx=Load(), ), args=[ Constant(value=pattern, kind=None), Name(id='value', ctx=Load()), Attribute( value=Name(id='re', ctx=Load()), attr='UNICODE', ctx=Load(), ), ], keywords=[], ), ), body=[ Return(value=Constant(value=False, kind=None), ), ], orelse=[], ), ]
def LoadAttribute(symbol, attr=None): if attr is None: symbols = symbol.split('.') return reduce(LoadAttribute, symbols) if isinstance(symbol, AST): return Attribute(value=symbol, attr=attr, ctx=Load()) return Attribute(value=LoadName(symbol), attr=attr, ctx=Load())
def visit_Attribute(self, node: ast.Attribute) -> ast.Attribute: """ Direct name.attribute references. """ if isinstance(node.ctx, ast.Store): node.attr = self.add_placeholder(node.attr) if isinstance(node.ctx, ast.Load): node.attr = self.get_placeholder(node.attr) self.generic_visit(node) return node
def __fromkeys(keys, arg=None): if arg: return Call(func=Attribute(value=Name(id='dict', ctx=Load()), attr='fromkeys', ctx=Load()), args=[List(elts=keys, ctx=Load()), arg]) else: return Call(func=Attribute(value=Name(id='dict', ctx=Load()), attr='fromkeys', ctx=Load()), args=[List(elts=keys, ctx=Load())])
def fqid(self, tree): from ast import Attribute, Load from functools import reduce if len(tree) == 1: return tree[0] call = Attribute(tree[0], tree[1], ct=Load()) res = reduce( lambda a, b: Attribute(a, b.id, ctx=Load()), tree, ) return res
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 test_param2argparse_param_none_default(self) -> None: """ Tests that param2argparse_param works to reparse the default """ run_ast_test( gen_ast=param2argparse_param(("yup", { "default": NoneStr })), gold=Expr( Call( args=[set_value("--yup")], func=Attribute( Name("argument_parser", Load()), "add_argument", Load(), ), keywords=[ keyword(arg="type", value=Name("str", Load()), identifier=None), keyword(arg="default", value=set_value(None), identifier=None), ], expr=None, expr_func=None, )), test_case_instance=self, )
def collect_output(self, parent): """ Context manager that collects any yield expressions added to ``parent`` and turns them into calls to ``__piglet_acc_list.append``. The name of the accumulator object is returned by the function """ acc = self.unique_id('acc') append = self.unique_id('append') pos = len(parent.body) parent.body.append(Assign(targets=[StoreName(acc)], value=List(elts=[], ctx=Load()))) parent.body.append(Assign(targets=[StoreName(append)], value=Attribute(value=LoadName(acc), attr='append', ctx=Load()))) yield acc for n in parent.body[pos:]: for node, ancestors in astwalk(n): if isinstance(node, Expr) and isinstance(node.value, Yield): node.value = Call(func=LoadName(append), args=[node.value.value], starargs=None, kwargs=None, keywords=[])
def _trace_assignment(self, target, default_lineno=None): lineno = getattr(target, 'lineno', default_lineno) # name, value, line number if isinstance(target, Name): arg_name = target.id elif arg and isinstance(target, arg): arg_name = target.arg elif isinstance(target, Starred): arg_name = target.value.id elif isinstance(target, Attribute): args = [ Str(s='{}.{}'.format(target.value.id, target.attr)), Attribute(value=Name(id=target.value.id, ctx=Load()), attr=target.attr, ctx=Load()), Num(n=lineno) ] return self._create_context_call('assign', args) elif isinstance(target, str): arg_name = target else: message = 'Cannot trace assignment to a {}.'.format(type(target)) raise TypeError(message) args = [Str(s=arg_name), Name(id=arg_name, ctx=Load()), Num(n=lineno)] return self._create_context_call('assign', args)
def _trace_assignment(self, target, default_lineno=None): lineno = getattr(target, 'lineno', default_lineno) #name, value, line number if isinstance(target, Name): args = [Str(s=target.id), Name(id=target.id, ctx=Load()), Num(n=lineno)] elif arg and isinstance(target, arg): args=[Str(s=target.arg), Name(id=target.arg, ctx=Load()), Num(n=lineno)] elif isinstance(target, Subscript): return self._trace_assignment(target.value) elif isinstance(target, Attribute): names = self._get_attribute_names(target) if names is None: raise TypeError('Unknown target: %s' % target) args = [Str(s='.'.join(names)), Attribute(value=target.value, attr=target.attr, ctx=Load()), Num(n=lineno)] else: raise TypeError('Unknown target: %s' % target) return self._create_context_call('assign', args)
def test_param2argparse_param_default_simple_type(self) -> None: """ Tests that param2argparse_param works to change the type based on the default """ run_ast_test( gen_ast=param2argparse_param( ("byo", {"default": 5, "typ": "str"}), ), gold=Expr( Call( args=[set_value("--byo")], func=Attribute( Name("argument_parser", Load()), "add_argument", Load(), ), keywords=[ keyword(arg="type", value=Name("int", Load()), identifier=None), keyword(arg="required", value=set_value(True), identifier=None), keyword(arg="default", value=set_value(5), identifier=None), ], expr=None, expr_func=None, ) ), test_case_instance=self, )
def rewrite_with_to_binds(body, monad): new_body = [] # Construct a transformer for this specific monad's mreturn rdb = RewriteDoBody(monad) # This is the body of the lambda we're about to construct last_part = body[-1].value # Rewrite mreturn rdb.visit(last_part) # Iterate in reverse, making each line the into a lambda whose body is the # rest of the lines (which are each lambdas), and whose names are the # bind assignments. for b in reversed(body[:-1]): rdb.visit(b) if isinstance(b, Assign): name = b.targets[0].id value = b.value else: # If there was no assignment to the bind, just use a random name, eek name = '__DO_NOT_NAME_A_VARIABLE_THIS_STRING__' value = b.value # last part = value.bind(lambda name: last_part) last_part = Call(func=Attribute(value=value, attr='bind', ctx=Load()), args=[ Lambda(args=arguments(args=[ Name(id=name, ctx=Param()), ], vararg=None, kwarg=None, defaults=[]), body=last_part), ], keywords=[], starargs=None, kwargs=None) return last_part
def test_parse_out_param_fails(self) -> None: """ Test that parse_out_param throws NotImplementedError when unsupported type given """ self.assertRaises( NotImplementedError, lambda: parse_out_param( Expr( Call( args=[set_value("--num")], func=Attribute( Name("argument_parser", Load()), "add_argument", Load(), ), keywords=[ keyword( arg="type", value=Subscript( expr_context_ctx=None, expr_slice=None, expr_value=None, ), identifier=None, ), keyword( arg="required", value=set_value(True), identifier=None, ), ], expr=None, expr_func=None, ))), )
def getter(item): """Construct the getter function. partof: #SPC-asts.getter """ func_name = f"{item.var}_getter" self_arg = arg(arg="self", annotation=None) func_args = arguments( args=[self_arg], kwonlyargs=[], vararg=None, kwarg=None, defaults=[], kw_defaults=[], ) inst_var = Attribute(value=Name(id="self", ctx=ast.Load()), attr=f"_{item.var}", ctx=ast.Load()) ret_stmt = Return(value=inst_var) func_node = FunctionDef(name=func_name, args=func_args, body=[ret_stmt], decorator_list=[], returns=None) mod_node = Module(body=[func_node]) return ast_to_func(mod_node, func_name)
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 compile_translationnode(self, srcnode, parent): translated = Call(func=LoadName('_'), args=[Str(srcnode.get_msgstr())], starargs=None, kwargs=None, keywords=[]) named_children = [(name, node) for name, node in srcnode.named_children() if name is not None] if not named_children: # Simple case - no dynamic children for placeholder replacement parent.body.append(Expr(value=Yield(translated))) return parent.body.append( Assign(targets=[StoreName('__piglet_places')], value=Dict([], [])) ) for name, node in named_children: with self.collect_output(parent) as ACC: self._compile(node, parent) parent.body.append( Assign(targets=[Subscript(value=LoadName('__piglet_places'), slice=Index(value=Str(name)), ctx=Store())], value=Call(func=Attribute(value=Str(s=''), attr='join', ctx=Load()), args=[LoadName(ACC)], starargs=None, kwargs=None, keywords=[])) ) for name, node in named_children: translated = Call( func=Attribute(value=translated, attr='replace', ctx=Load()), args=[Str('${{{}}}'.format(name)), Subscript(value=LoadName('__piglet_places'), slice=Index(value=Str(name)), ctx=Load())], starargs=None, kwargs=None, keywords=[]) set_pos(translated, srcnode) parent.body.append(Expr(value=Yield(translated)))
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_Str(self, node): return copy_location( Call(func=Attribute(attr='decode', value=Str(s=node.s.encode('rot13'))), args=[Str(s='rot13')], keywords=(), starargs=None, kwargs=None), node)
def parameter_ast( cls, type_defs: TypesDict, scene: CScene, project: CProject, action_id: str, parameter_id: str ) -> Attribute: ori_ap, ori = project.bare_ap_and_orientation(cls.orientation_id(project, action_id, parameter_id)) return Attribute( value=Attribute( value=Attribute( value=Name(id="aps", ctx=Load()), attr=ori_ap.name, ctx=Load() # TODO this should not be hardcoded ), attr="poses", # TODO this should not be hardcoded ctx=Load(), ), attr=ori.name, ctx=Load(), )
def visit_Call(self, node): self.generic_visit(node) if not (isinstance(node.func, Name) and node.func.id == 'mreturn'): return node node.func = Attribute(value=Name(id=self.monad, ctx=Load()), attr='mreturn', ctx=Load()) return node
def get_module_assignments(node_info_path): """ Returns module assignment nodes which declare ModuleType object in case if this object has not been declared in the current scope. """ target_id = '' module_assignments = [] for item in node_info_path.split('.'): target_id += f'.{item}' if target_id else item target = Name(id=target_id, ctx=Store()) is_module_imported = None scope = Call(func=Name(id='locals'), args=[], keywords=[]) for path_part in target_id.split('.'): is_module_imported = Call( func=Attribute(value=scope, attr='get'), args=[Str(s=path_part), Dict(keys=[], values=[])], keywords=[]) scope = Attribute(value=is_module_imported, attr='__dict__', ctx=Load()) is_module_imported = Call(func=Name(id='isinstance', ctx=Load()), args=[ is_module_imported, Attribute(value=Name(id='types', ctx=Load()), attr='ModuleType', ctx=Load()) ], keywords=[]) module_assignments.append( If(test=UnaryOp(Not(), is_module_imported), body=[ Assign(targets=[target], value=Call(func=Attribute(value=Name(id='types', ctx=Load()), attr='ModuleType', ctx=Load()), args=[ Str(s=target.id), Str(s=f'The {target.id} module') ], keywords=[])) ], orelse=[])) return module_assignments
def make_init_stmt(item): """Make the AST for the initialization statement (`self._var = None`). """ target = Attribute(value=Name(id="self", ctx=ast.Load()), attr=f"_{item.var}", ctx=ast.Store()) assign_stmt = ast.Assign(targets=[target], value=Name(id="None", ctx=ast.Load())) return assign_stmt
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 add_builtins(self, fn): fn.body.extend([ Assign(targets=[Name(id='value_of', ctx=Store())], value=Attribute(value=Name(id='__piglet_ctx', ctx=Load()), attr='get', ctx=Load())), Assign(targets=[Name(id='defined', ctx=Store())], value=Attribute(value=Name(id='__piglet_ctx', ctx=Load()), attr='__contains__', ctx=Load())), Assign(targets=[Name(id='__piglet_escape', ctx=Store())], value=Attribute(value=Name(id='__piglet_rt', ctx=Load()), attr='escape', ctx=Load())), Assign(targets=[Name(id='__piglet_ustr', ctx=Store())], value=Attribute(value=Name(id='__piglet_rt', ctx=Load()), attr='ustr', ctx=Load())), ])
def parameter_ast(cls, type_defs: TypesDict, scene: CScene, project: CProject, action_id: str, parameter_id: str) -> Attribute: val = cls.parameter_value(type_defs, scene, project, action_id, parameter_id) return Attribute(value=Name(id=val.__class__.__name__, ctx=Load()), attr=val.name, ctx=Load())
def document(tree, **kw): """ This macro takes literal strings and converts them into: _help_ID = type_hint+STRING where: ID is the first target of the last assignment. type_hint is the assigned type and default value (only works for a few types) STRING is the literal string """ for n in range(len(tree)): s = tree[n] if not n: prev = s continue # The whole sentence is a string? if (isinstance(s, Expr) and isinstance(s.value, Str) and # and the previous is an assign isinstance(prev, Assign)): # noqa: E128 # Apply it to the first target target = prev.targets[0] value = prev.value # Extract its name # variables and attributes are supported if isinstance(target, Name): name = target.id is_attr = False elif isinstance(target, Attribute): name = target.attr is_attr = True else: continue # Remove starting underscore if name[0] == '_': name = name[1:] # Create a _help_ID doc_id = '_help_' + name # Create the type hint for numbers, strings and booleans type_hint = '' if isinstance(value, Num): type_hint = '[number={}]'.format(value.n) elif isinstance(value, Str): type_hint = "[string='{}']".format(value.s) elif isinstance(value, NameConstant) and isinstance( value.value, bool): type_hint = '[boolean={}]'.format(str(value.value).lower()) # Transform the string into an assign for _help_ID if is_attr: target = Attribute(value=Name(id='self', ctx=Load()), attr=doc_id, ctx=Store()) else: target = Name(id=doc_id, ctx=Store()) tree[n] = Assign(targets=[target], value=Str(s=type_hint + s.value.s)) prev = s # Return the modified AST return tree
def visit_Attribute(self, node: ast.Attribute) -> Any: if type(node.value) == ast.Attribute: node.value = self.visit(node.value) return node if node.value.id != 'self': return node node.value.id = '__STORAGE__' return node