def _create_assign_lambda(s, o, lamb): assert isinstance( o, Signal ), "You can only assign(//=) a lambda function to a Wire/InPort/OutPort." srcs, line = inspect.getsourcelines(lamb) assert len( srcs ) == 1, "We can only handle single-line lambda connect right now." src = compiled_re.sub(r'\2', srcs[0]).lstrip(' ') root = ast.parse(src) assert isinstance(root, ast.Module) and len( root.body) == 1, "Invalid lambda (contact pymtl3 developer)" root = root.body[0] assert isinstance(root, ast.AugAssign) and isinstance( root.op, ast.FloorDiv) lhs, rhs = root.target, root.value # We expect the lambda to have no argument: # {'args': [], 'vararg': None, 'kwonlyargs': [], 'kw_defaults': [], 'kwarg': None, 'defaults': []} assert isinstance( rhs, ast.Lambda ) and not rhs.args.args and rhs.args.vararg is None, \ "The lambda shouldn't contain any argument." rhs = rhs.body # Compose a new and valid function based on the lambda's lhs and rhs # Note that we don't need to add those source code of closure var # assignment to linecache. To get the matching line number in the # error message, we set the line number of update block blk_name = "_lambda__{}".format(repr(o).replace(".", "_")) lambda_upblk = ast.FunctionDef( name=blk_name, args=ast.arguments(args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=[ ast.Assign(targets=[lhs], value=rhs, lineno=2, col_offset=6) ], decorator_list=[], returns=None, lineno=1, col_offset=4, ) lambda_upblk_module = ast.Module(body=[lambda_upblk]) # Manually wrap the lambda upblk with a closure function that adds the # desired variables to the closure of `_lambda__*` # We construct AST for the following function to add free variables in the # closure of the lambda function to the closure of the generated lambda # update block. # # def closure( lambda_closure ): # <FreeVarName1> = lambda_closure[<Idx1>].cell_contents # <FreeVarName2> = lambda_closure[<Idx2>].cell_contents # ... # <FreeVarNameN> = lambda_closure[<IdxN>].cell_contents # def _lambda__<lambda_blk_name>(): # # the assignment statement appears here # return _lambda__<lambda_blk_name> new_root = ast.Module(body=[ ast.FunctionDef( name="closure", args=ast.arguments(args=[ ast.arg(arg="lambda_closure", annotation=None, lineno=1, col_offset=12) ], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=[ ast.Assign( targets=[ ast.Name(id=var, ctx=ast.Store(), lineno=1 + idx, col_offset=2) ], value=ast.Attribute( value=ast.Subscript( value=ast.Name( id='lambda_closure', ctx=ast.Load(), lineno=1 + idx, col_offset=5 + len(var), ), slice=ast.Index(value=ast.Num( n=idx, lineno=1 + idx, col_offset=19 + len(var), ), ), ctx=ast.Load(), lineno=1 + idx, col_offset=5 + len(var), ), attr='cell_contents', ctx=ast.Load(), lineno=1 + idx, col_offset=5 + len(var), ), lineno=1 + idx, col_offset=2, ) for idx, var in enumerate(lamb.__code__.co_freevars) ] + [lambda_upblk] + [ ast.Return( value=ast.Name( id=blk_name, ctx=ast.Load(), lineno=4 + len(lamb.__code__.co_freevars), col_offset=9, ), lineno=4 + len(lamb.__code__.co_freevars), col_offset=2, ) ], decorator_list=[], returns=None, lineno=1, col_offset=0, ) ]) # In Python 3 we need to supply a dict as local to get the newly # compiled function from closure. # Then `closure(lamb.__closure__)` returns the lambda update block with # the correct free variables in its closure. dict_local = {} exec(compile(new_root, blk_name, "exec"), lamb.__globals__, dict_local) blk = dict_local['closure'](lamb.__closure__) # Add the source code to linecache for the compiled function new_src = "def {}():\n {}\n".format(blk_name, src.replace("//=", "=")) linecache.cache[blk_name] = (len(new_src), None, new_src.splitlines(), blk_name) ComponentLevel1.update(s, blk) # This caching here does no caching because the block name contains # the signal name intentionally to avoid conflicts. With //= it is # more possible than normal update block to have conflicts: # if param == 1: s.out //= s.in_ + 1 # else: s.out //= s.out + 100 # Here these two blocks will implicity have the same name but they # have different contents based on different param. # So the cache call here is just to reuse the existing interface to # register the AST/src of the generated block for elaborate or passes # to use. s._cache_func_meta(blk, is_update_ff=False, given=("".join(srcs), lambda_upblk_module, line, inspect.getsourcefile(lamb))) return blk
def repr(self, load_name_node): return ast.Call(func=ast.Name('repr', ast.Load()), args=[load_name_node], keywords=[])
def visit_BinOp(self, node): if node.op.__class__ in self.operators: sympy_class = self.operators[node.op.__class__] right = self.visit(node.right) left = self.visit(node.left) if isinstance(node.left, ast.UnaryOp) and (isinstance( node.right, ast.UnaryOp) == 0) and sympy_class in ('Mul', ): left, right = right, left if isinstance(node.op, ast.Sub): right = ast.UnaryOp(op=ast.USub(), operand=right) if isinstance(node.op, ast.Div): if isinstance(node.left, ast.UnaryOp): if isinstance(node.right, ast.UnaryOp): left, right = right, left left = ast.Call(func=ast.Name(id='Pow', ctx=ast.Load()), args=[ left, ast.UnaryOp(op=ast.USub(), operand=ast.Num(1)) ], keywords=[ ast.keyword(arg='evaluate', value=ast.Name( id='False', ctx=ast.Load())) ], starargs=None, kwargs=None) else: right = ast.Call(func=ast.Name(id='Pow', ctx=ast.Load()), args=[ right, ast.UnaryOp(op=ast.USub(), operand=ast.Num(1)) ], keywords=[ ast.keyword(arg='evaluate', value=ast.Name( id='False', ctx=ast.Load())) ], starargs=None, kwargs=None) new_node = ast.Call(func=ast.Name(id=sympy_class, ctx=ast.Load()), args=[left, right], keywords=[ ast.keyword(arg='evaluate', value=ast.Name(id='False', ctx=ast.Load())) ], starargs=None, kwargs=None) if sympy_class in ('Add', 'Mul'): # Denest Add or Mul as appropriate new_node.args = self.flatten(new_node.args, sympy_class) return new_node return node
def name(tree): "Splices a string value into the quoted code snippet as a Name." # TODO: another hard-coded call now assuming `ast.Name` return Literal(compat.Call(ast.Attribute( value=ast.Name(id='ast', ctx=ast.Load()), attr='Name', ctx=ast.Load()), [], [ast.keyword("id", tree)]))
def visit_Call(self, call_node): func_node = call_node.func if isinstance(func_node, ast.Name) and func_node.id == "isinstance": # original code was: # assert isinstance(obj, cls_or_tuple) # # generated code is: # # @contexts_assertion_var1 = obj # @contexts_assertion_var2 = cls_or_tuple # @contexts_assertion_var3 = obj.__class__ # @contexts_assertion_var4 = (tuple(@x.__name__ for @x in @contexts_assertion_var2) # if isinstance(@contexts_assertion_var2, tuple) # else @contexts_assertion_var2.__name__) # assert isinstance(@contexts_assertion_var1, @contexts_assertion_var2), 'Asserted isinstance({0}, {1}) but found it to be a {2}'.format(@contexts_assertion_var1, repr(@contexts_assertion_var4).replace("'", ""), @contexts_assertion_var3) return [ self.assign('@contexts_assertion_var1', call_node.args[0]), self.assign('@contexts_assertion_var2', call_node.args[1]), self.assign('@contexts_assertion_var3', self.clsname(self.getattr(self.load('@contexts_assertion_var1'), '__class__'))), self.assign('@contexts_assertion_var4', ast.IfExp( ast.Call(func=self.load('isinstance'), args=[ self.load('@contexts_assertion_var2'), self.load('tuple'), ], keywords=[]), ast.Call(func=self.load('tuple'), args=[ ast.GeneratorExp(self.clsname(self.load('@x')), [ ast.comprehension(ast.Name('@x', ast.Store()), self.load('@contexts_assertion_var2'), []), ]), ], keywords=[]), self.clsname(self.load('@contexts_assertion_var2')) )), ast.Assert( ast.Call(func=ast.Name(id='isinstance', ctx=ast.Load()), args=[ self.load('@contexts_assertion_var1'), self.load('@contexts_assertion_var2'), ], keywords=[]), self.format('Asserted isinstance({0}, {1}) but found it to be a {2}', [ self.repr(self.load('@contexts_assertion_var1')), ast.Call(func=self.getattr(self.repr(self.load('@contexts_assertion_var4')), 'replace'), args=[ast.Str("'"), ast.Str("")], keywords=[]), self.load('@contexts_assertion_var3'), ])) ] if isinstance(func_node, ast.Name) and func_node.id == "all": # original code was: # # assert all(iterable) # # generated code is: # # @contexts_assertion_var1 = iterable # for @contexts_assertion_var_ix, @contexts_assertion_var_elem in enumerate(@contexts_assertion_var1): # assert x, "Not all elements of {} were truthy. First falsy element: {} at position {}".format(@contexts_assertion_var1, @contexts_assertion_var_ix, @contexts_assertion_var_elem) return [ self.assign('@contexts_assertion_var1', call_node.args[0]), ast.For(ast.Tuple([ast.Name("@contexts_assertion_var_ix", ast.Store()), ast.Name("@contexts_assertion_var_elem", ast.Store())], ast.Store()), ast.Call(func=self.load("enumerate"), args=[self.load('@contexts_assertion_var1')], keywords=[]), [ ast.Assert( self.load('@contexts_assertion_var_elem'), self.format("Not all elements of {0} were truthy. First falsy element: {1} at position {2}", [ self.repr(self.load('@contexts_assertion_var1')), self.repr(self.load('@contexts_assertion_var_elem')), self.load('@contexts_assertion_var_ix'), ])) ], []) ]
def Name(id): #@ReservedAssignment return ast.Name(id=id)
def semicolon(f): """Add a semicolon to the result of a visit_* call. Parameters ---------- f : callable """ @functools.wraps(f) def wrapper(*args, **kwargs): return f(*args, **kwargs) + ';' return wrapper @rewrite.register(ast.Call(func=ast.Name(id='print'))) def rewrite_print(node): return ast.Call( func=ast.Attribute( value=ast.Name(id='console', ctx=ast.Load()), attr='log', ctx=ast.Load(), ), args=node.args, keywords=node.keywords, ) @rewrite.register(ast.Call(func=ast.Name(id='len'))) def rewrite_len(node): assert len(node.args) == 1
def run(self, interpreter: Interpreter): pid = interpreter.stack.pop() interpreter.stack.append( ast.Call( ast.Attribute(ast.Name("UNPICKLER", ast.Load()), "persistent_load"), [pid], []))
def visit_named_temp_file(self, node, vargs): node.annotation = ast.Name(id="tempfile._TemporaryFileWrapper") node.result_type = True return "NamedTempFile::new()"
def visit_While(self, node): while_begin_save = self.while_begin while_end_save = self.while_end while_id = self.id_count self.id_count += 1 begin_name = '_ket_tmp_while_begin' + str(while_id) loop_name = '_ket_tmp_while_loop' + str(while_id) end_name = '_ket_tmp_while_end' + str(while_id) else_name = None self.while_end = end_name if node.orelse: else_name = '_ket_tmp_while_else' + str(while_id) while_begin = ast.Assign(targets=[ ast.Tuple(elts=[ ast.Name(id=name, ctx=ast.Store()) for name in [begin_name, loop_name, else_name, end_name] ], ctx=ast.Store()) ], value=ast.Call(func=ast.Name( id='_ket_while_else', ctx=ast.Load()), args=[], keywords=[])) else: while_begin = ast.Assign(targets=[ ast.Tuple(elts=[ ast.Name(id=name, ctx=ast.Store()) for name in [begin_name, loop_name, end_name] ], ctx=ast.Store()) ], value=ast.Call(func=ast.Name( id='_ket_while', ctx=ast.Load()), args=[], keywords=[])) test_name = '_ket_while_test' + str(while_id) test_assing = ast.Assign( targets=[ast.Name(id=test_name, ctx=ast.Store())], value=node.test) type_check = ast.Call(func=ast.Name(id='_ket_is_future', ctx=ast.Load()), args=[ast.Name(id=test_name, ctx=ast.Load())], keywords=[]) body_call = ast.Expr(value=ast.Call( func=ast.Name(id='_ket_while_body', ctx=ast.Load()), args=[ ast.Name(id=test_name, ctx=ast.Load()), ast.Name(id=loop_name, ctx=ast.Load()), ast.Name(id=else_name if else_name is not None else end_name, ctx=ast.Load()) ], keywords=[])) loop_call = ast.Expr(value=ast.Call( func=ast.Name(id='_ket_loop', ctx=ast.Load()), args=[ ast.Name(id=begin_name, ctx=ast.Load()), ast.Name(id=else_name if else_name is not None else end_name, ctx=ast.Load()) ], keywords=[])) else_call = [ ast.Expr( value=ast.Call(func=ast.Name(id='_ket_next', ctx=ast.Load()), args=[ast.Name(id=end_name, ctx=ast.Load())], keywords=[])) ] if else_name is not None else [] node_cp = copy.deepcopy(node) in_while_save = self.in_while self.in_while = True self.generic_visit(node) self.in_while = in_while_save self.generic_visit(node_cp) ndone_name = '_ket_tmp_while_ndone' + str(while_id) if_not_future = ast.If( test=ast.Name(id=test_name, ctx=ast.Load()), body=[ ast.Assign(targets=[ast.Name(id=ndone_name, ctx=ast.Store())], value=ast.Constant(value=True)), ast.While(test=ast.Name(id=ndone_name, ctx=ast.Load()), body=[ *node_cp.body, ast.If(test=ast.UnaryOp(op=ast.Not(), operand=node_cp.test), body=[ ast.Assign( targets=[ ast.Name(id=ndone_name, ctx=ast.Store()) ], value=ast.Constant(value=False)) ], orelse=[]) ], orelse=[]), ast.If(test=ast.UnaryOp(op=ast.Not(), operand=ast.Name(id=ndone_name, ctx=ast.Load())), body=node_cp.orelse if node_cp.orelse else [ast.Pass()], orelse=[]) ], orelse=node_cp.orelse) if_future = ast.If(test=type_check, body=[body_call, *node.body, loop_call, *else_call], orelse=[if_not_future]) self.while_begin = while_begin_save self.while_end = while_end_save return [while_begin, test_assing, if_future]
def astconv_func_param(param_astc, ctx, prefix_stmts): return ast.Assign( targets=[ast.Name(id=param_astc.spelling, ctx=ast.Store())], value=call(attr('__globals__', TYPE_MAP[param_astc.type.kind]), attr(param_astc.spelling)))
def visit_If(self, node): if_id = self.id_count self.id_count += 1 self.generic_visit(node) node_cp = copy.deepcopy(node) _test_name = '_ket_temp_if_test' + str(if_id) test_name = ast.Name(id=_test_name, ctx=ast.Load()) end_name = '_ket_tmp_if_end' + str(if_id) else_name = None if node.orelse: else_name = '_ket_tmp_if_else' + str(if_id) if_begin = ast.Assign(targets=[ ast.Tuple(elts=[ ast.Name(id=else_name, ctx=ast.Store()), ast.Name(id=end_name, ctx=ast.Store()) ], ctx=ast.Store()) ], value=ast.Call(func=ast.Name( id='_ket_if_else', ctx=ast.Load()), args=[test_name], keywords=[])) else: if_begin = ast.Assign(targets=[ ast.Name(id=end_name, ctx=ast.Store()), ], value=ast.Call(func=ast.Name(id='_ket_if', ctx=ast.Load()), args=[test_name], keywords=[])) if_body = [if_begin, *node.body] if else_name is not None: else_call = ast.Expr( value=ast.Call(func=ast.Name(id='_ket_else', ctx=ast.Load()), args=[ ast.Name(id=name, ctx=ast.Load()) for name in [else_name, end_name] ], keywords=[])) if_body.extend([else_call, *node.orelse]) if_body.append( ast.Expr( value=ast.Call(func=ast.Name(id='_ket_next', ctx=ast.Load()), args=[ast.Name(id=end_name, ctx=ast.Load())], keywords=[]))) test_assing = ast.Assign( targets=[ast.Name(id=_test_name, ctx=ast.Store())], value=node.test) type_check = ast.Call(func=ast.Name(id='_ket_is_future', ctx=ast.Load()), args=[test_name], keywords=[]) node_cp.test = test_name if_future = ast.If(test=type_check, body=if_body, orelse=[node_cp]) return [test_assing, if_future]
def visit_Continue(self, node): return ast.Expr(value=ast.Call( func=ast.Name(id='_ket_goto', ctx=ast.Load()), args=[ast.Name(id=self.while_begin, ctx=ast.Load())], keywords=[])) if self.in_while else node
def visit_Assign(self, node): assert (len(node.targets) == 1) self.generic_visit(node) is_static_assign = isinstance( node.value, ast.Call) and ASTResolver.resolve_to( node.value.func, ti.static, globals()) if is_static_assign: return node if isinstance(node.targets[0], ast.Tuple): targets = node.targets[0].elts # Create stmts = [] holder = self.parse_stmt('__tmp_tuple = ti.expr_init_list(0, ' f'{len(targets)})') holder.value.args[0] = node.value stmts.append(holder) def tuple_indexed(i): indexing = self.parse_stmt('__tmp_tuple[0]') self.set_subscript_index(indexing.value, self.parse_expr("{}".format(i))) return indexing.value for i, target in enumerate(targets): is_local = isinstance(target, ast.Name) if is_local and self.is_creation(target.id): var_name = target.id target.ctx = ast.Store() # Create, no AST resolution needed init = ast.Attribute(value=ast.Name(id='ti', ctx=ast.Load()), attr='expr_init', ctx=ast.Load()) rhs = ast.Call( func=init, args=[tuple_indexed(i)], keywords=[], ) self.create_variable(var_name) stmts.append(ast.Assign(targets=[target], value=rhs)) else: # Assign target.ctx = ast.Load() func = ast.Attribute(value=target, attr='assign', ctx=ast.Load()) call = ast.Call(func=func, args=[tuple_indexed(i)], keywords=[]) stmts.append(ast.Expr(value=call)) for stmt in stmts: ast.copy_location(stmt, node) stmts.append(self.parse_stmt('del __tmp_tuple')) return self.make_single_statement(stmts) else: is_local = isinstance(node.targets[0], ast.Name) if is_local and self.is_creation(node.targets[0].id): var_name = node.targets[0].id # Create, no AST resolution needed init = ast.Attribute(value=ast.Name(id='ti', ctx=ast.Load()), attr='expr_init', ctx=ast.Load()) rhs = ast.Call( func=init, args=[node.value], keywords=[], ) self.create_variable(var_name) return ast.copy_location( ast.Assign(targets=node.targets, value=rhs), node) else: # Assign node.targets[0].ctx = ast.Load() func = ast.Attribute(value=node.targets[0], attr='assign', ctx=ast.Load()) call = ast.Call(func=func, args=[node.value], keywords=[]) return ast.copy_location(ast.Expr(value=call), node)
def merge_models(self, var_name, model_graph, args): """Merge a model used in a random variable assignment. """ # The returned node now become a standard node name_returned = model_graph.returned_variables[0] model_graph.nodes[name_returned]["content"].is_returned = False # We first rename the nodes by appending the name of the # model to the variables names. This prevents overlap # when the same variable name has been used in multiple # model definitions. # The returned variable of the model being merged is rename # to the variable being assigned in the current model. mapping = { name: name + "_{}".format(model_graph.name) for name in model_graph.nodes } mapping.update({name_returned: var_name}) model_graph = nx.relabel_nodes(model_graph, mapping) # update the nodes' internal names for name, node in model_graph.nodes(data=True): node["content"].name = name # Update the name of the arguments in the graph being merged. for _, content in model_graph.nodes(data=True): node = content["content"] if isinstance(node, Transformation) or isinstance(node, RandVar): node.args = [ mapping[arg] if isinstance(arg, str) else arg for arg in node.args ] if isinstance(node, Transformation): relabel_arguments(node.expression, mapping) else: distribution_args = [] for arg in node.distribution.args: if isinstance(arg, ast.Name): arg = ast.Name(id=mapping[arg.id], ctx=ast.Load()) distribution_args.append(arg) node.distribution.args = distribution_args # Update the arguments with their value if provided for i, arg in enumerate(model_graph.arguments): if len(args) - 1 >= i: model_graph.remove_node(arg) if isinstance(args[i], int): value = ast.Constant(value=args[i]) elif isinstance(args[i], str): value = ast.Name(id=args[i], ctx=ast.Load()) model_graph.add_variable(arg, value) else: if model_graph.nodes[arg]["content"].default_value is None: raise TypeError( "{} missing one require positional argument: '{}'". format(model_graph.name, arg)) # Beware that the merged graph takes the name of the first # argument's. It is important to keep it this way to keep # the name hierarchy. return nx.compose(model_graph, self)
def _compile_directive_call_assets(self, el, options): """ This special 't-call' tag can be used in order to aggregate/minify javascript and css assets""" if len(el): raise SyntaxError("t-call-assets cannot contain children nodes") # nodes = self._get_asset(xmlid, options, css=css, js=js, debug=values.get('debug'), async=async, values=values) # # for index, (tagName, t_attrs, content) in enumerate(nodes): # if index: # append('\n ') # append('<') # append(tagName) # # self._post_processing_att(tagName, t_attrs, options) # for name, value in t_attrs.items(): # if value or isinstance(value, string_types)): # append(u' ') # append(name) # append(u'="') # append(escape(pycompat.to_text((value))) # append(u'"') # # if not content and tagName in self._void_elements: # append('/>') # else: # append('>') # if content: # append(content) # append('</') # append(tagName) # append('>') # space = el.getprevious() is not None and el.getprevious().tail or el.getparent().text sep = u'\n' + space.rsplit('\n').pop() return [ ast.Assign( targets=[ast.Name(id='nodes', ctx=ast.Store())], value=ast.Call( func=ast.Attribute( value=ast.Name(id='self', ctx=ast.Load()), attr='_get_asset_nodes', ctx=ast.Load() ), args=[ ast.Str(el.get('t-call-assets')), ast.Name(id='options', ctx=ast.Load()), ], keywords=[ ast.keyword('css', self._get_attr_bool(el.get('t-css', True))), ast.keyword('js', self._get_attr_bool(el.get('t-js', True))), ast.keyword('debug', ast.Call( func=ast.Attribute( value=ast.Name(id='values', ctx=ast.Load()), attr='get', ctx=ast.Load() ), args=[ast.Str('debug')], keywords=[], starargs=None, kwargs=None )), ast.keyword('async_load', self._get_attr_bool(el.get('async_load', False))), ast.keyword('values', ast.Name(id='values', ctx=ast.Load())), ], starargs=None, kwargs=None ) ), ast.For( target=ast.Tuple(elts=[ ast.Name(id='index', ctx=ast.Store()), ast.Tuple(elts=[ ast.Name(id='tagName', ctx=ast.Store()), ast.Name(id='t_attrs', ctx=ast.Store()), ast.Name(id='content', ctx=ast.Store()) ], ctx=ast.Store()) ], ctx=ast.Store()), iter=ast.Call( func=ast.Name(id='enumerate', ctx=ast.Load()), args=[ast.Name(id='nodes', ctx=ast.Load())], keywords=[], starargs=None, kwargs=None ), body=[ ast.If( test=ast.Name(id='index', ctx=ast.Load()), body=[self._append(ast.Str(sep))], orelse=[] ), self._append(ast.Str(u'<')), self._append(ast.Name(id='tagName', ctx=ast.Load())), ] + self._append_attributes() + [ ast.If( test=ast.BoolOp( op=ast.And(), values=[ ast.UnaryOp(ast.Not(), ast.Name(id='content', ctx=ast.Load()), lineno=0, col_offset=0), ast.Compare( left=ast.Name(id='tagName', ctx=ast.Load()), ops=[ast.In()], comparators=[ast.Attribute( value=ast.Name(id='self', ctx=ast.Load()), attr='_void_elements', ctx=ast.Load() )] ), ] ), body=[self._append(ast.Str(u'/>'))], orelse=[ self._append(ast.Str(u'>')), ast.If( test=ast.Name(id='content', ctx=ast.Load()), body=[self._append(ast.Name(id='content', ctx=ast.Load()))], orelse=[] ), self._append(ast.Str(u'</')), self._append(ast.Name(id='tagName', ctx=ast.Load())), self._append(ast.Str(u'>')), ] ) ], orelse=[] ) ]
def reevaluate(self, new_node, glb, lcl): if not self.objects: # pragma: no cover return ext = new_node.extent closure = False lcl = {} new_node = type(new_node)( name=new_node.name, args=new_node.args, body=new_node.body, decorator_list=[], returns=new_node.returns, type_comment=new_node.type_comment, lineno=new_node.lineno, col_offset=new_node.col_offset, end_lineno=new_node.end_lineno, end_col_offset=new_node.end_col_offset, ) previous = lcl.get(self.name, None) if self.variables.closure: closure = True names = tuple(sorted(self.variables.closure)) wrap = ast.copy_location( ast.FunctionDef( name="##create_closure", args=ast.arguments( posonlyargs=[], args=[ ast.arg(arg=name, lineno=new_node.lineno, col_offset=0) for name in names ], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[], ), body=[ new_node, ast.Return(ast.Name(id=new_node.name, ctx=ast.Load())), ], decorator_list=[], returns=None, ), new_node, ) ast.fix_missing_locations(wrap) node = ast.Module(body=[wrap], type_ignores=[]) else: node = ast.Module(body=[new_node], type_ignores=[]) code = compile(node, mode="exec", filename=ext.filename) exec(code, glb, lcl) if closure: creator = lcl["##create_closure"] # It does not matter what arguments we provide here, because we will move the # function's __code__ elsewhere, so it will use a different closure new_obj = creator(*names) else: new_obj = lcl[self.name] lcl[self.name] = previous for obj in self.objects: conform(obj, new_obj) node.extent = ext self.node = node
def add_kwarg_to_super_call(super_call, kwarg): super_call.value.kwargs = ast.Name(id=kwarg, ctx=ast.Load())
def param(self, name, default=None): self.node.args.append(ast.Name(id=name)) if default != None: self.node.defaults.append(E(default)) return self
def add_vararg_to_super_call(super_call, vararg): super_call.value.starargs = ast.Name(id=vararg, ctx=ast.Load())
def u(tree): """Splices a value into the quoted code snippet, converting it into an AST via ast_repr.""" return Literal(compat.Call(ast.Name(id="ast_repr"), [tree], []))
def add_kwarg_to_super_call(super_call, kwarg): super_call.value.keywords.append( ast.keyword(arg=None, value=ast.Name(id=kwarg.arg, ctx=ast.Load())))
def ast_list(tree): """Splices a list of ASTs into the quoted code snippet as a List node.""" return Literal(compat.Call(ast.Attribute( value=ast.Name(id='ast', ctx=ast.Load()), attr='List', ctx=ast.Load()), [], [ast.keyword("elts", tree)]))
def add_vararg_to_super_call(super_call, vararg): super_call.value.args.append( ast.Starred(ctx=ast.Load(), value=ast.Name(id=vararg.arg, ctx=ast.Load())))
def assign(self, name, expr_node): return ast.Assign([ast.Name(name, ast.Store())], expr_node)
def _load_name(self, var_name, is_cellvar=False): src = ast.Name(var_name, ast.Load()) src.variable = Variable.from_variable(self.symtab[var_name]) src.variable.is_cellvar = is_cellvar src.type = src.variable.type return src
def load(self, name): return ast.Name(name, ast.Load())
from astpretty import pprint from ast import parse # from moshmosh.extensions import pattern_matching import ast print_ast = ast.Name("print", ast.Load()) pprint(parse(""" 1 and 2 """))
def var(id): return ast.Name(id=id, ctx=ast.Load())
def visit_Num(self, node): if isinstance(node.n, int): return ast.Call(func=ast.Name(id='Integer', ctx=ast.Load()), args=[node], keywords=[]) return node