def visit_Dict(self, node: ast.Dict): traced_keys: List[Optional[ast.expr]] = [] traced_values: List[ast.expr] = [] for k, v in zip(node.keys, node.values): is_dict_unpack = (k is None) if is_dict_unpack: traced_keys.append(None) else: with fast.location_of(k): traced_keys.append(fast.Call( func=self._emitter_ast(), args=[TraceEvent.dict_key.to_ast(), self._get_copy_id_ast(k)], keywords=fast.kwargs( ret=self.visit(k), value_node_id=self._get_copy_id_ast(v), dict_node_id=self._get_copy_id_ast(node), ) )) with fast.location_of(v): if is_dict_unpack: key_node_id_ast = fast.NameConstant(None) else: key_node_id_ast = self._get_copy_id_ast(k) traced_values.append(fast.Call( func=self._emitter_ast(), args=[TraceEvent.dict_value.to_ast(), self._get_copy_id_ast(v)], keywords=fast.kwargs( ret=self.visit(v), key_node_id=key_node_id_ast, dict_node_id=self._get_copy_id_ast(node), ) )) node.keys = traced_keys node.values = traced_values return self.visit_literal(node, should_inner_visit=False)
def getGlobalVariable(name): # _lambda_0 return Assign( targets=[ Name( id=name + '_locals', ctx=Store() ) ], value=Dict(keys=[], values=[]), type_comment=None)
def dict(self, d: List[Tree]): d = d[0] if d.data == self.DICT_OR_SET_MAKER: kv_pairs = [] data = d.children for i in range(0, len(data) - 1, 2): kv_pairs.append((data[i], data[i + 1])) keys = [k for k, _ in kv_pairs] values = [v for _, v in kv_pairs] return Dict(keys, values) return
def visit_Dict(self, node: ast.Dict): '''Process a dictionary. We create a C++ representation of this. The dict, as things currently stand, will not make its way into C++, but it might help us sort out some sort of output or similar. Args: node (ast.Dict): The dictionary node for us to process ''' if not all(v is not None for v in node.keys): raise ValueError('The python construction of adding a dictionary into another dictionary is not supported ({1: 10, **old_dict})') values = {k: self.get_rep(v, retain_scope=True) for k, v in zip(node.keys, node.values)} node.rep = crep.cpp_dict(values, self._gc.current_scope()) # type: ignore self._result = node.rep # type: ignore
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 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 test_param2ast_with_assign_dict(self) -> None: """Check that `param2ast` behaves correctly with dict type""" run_ast_test( self, param2ast( ("menthol", {"typ": "dict"}), ), gold=AnnAssign( annotation=set_slice(Name("dict", Load())), simple=1, target=Name("menthol", Store()), value=Dict(keys=[], values=[], expr=None), expr=None, expr_target=None, expr_annotation=None, ), )
def visit_Call(self, node): if is_unquoting(node.func): if isinstance(node.func, Name) and node.func.id == "_x": n = node.func node.func = copy_loc( n, Attribute( # FIXME that shit will explode value=copy_loc(n, Name(id="worm", ctx=Load())), attr="expand", ctx=Load(), ), ) tr = RewriteTopLevel() node.args = list(map(tr.visit, node.args)) for kw in node.keywords: kw.value = self.visit(kw.value) else: raise NotImplementedError() return node else: return self.make_node( node, "call", values=[ self.visit(node.func), copy_loc( node, List(elts=list(map(self.visit, node.args)), ctx=Load()) ), copy_loc( node, Dict( keys=[Constant(k.arg) for k in node.keywords], values=[self.visit(k.value) for k in node.keywords], ), ), ], )
def param2ast(param): """ Converts a param to an AnnAssign :param param: Name, dict with keys: 'typ', 'doc', 'default' :type param: ```Tuple[str, dict]``` :return: AST node for assignment :rtype: ```Union[AnnAssign, Assign]``` """ name, _param = param del param if _param.get("typ") is None and "default" in _param: _param["typ"] = type(_param["default"]).__name__ if "default" in _param and isinstance(_param["default"], (Constant, Str)): _param["default"] = get_value(_param["default"]) if _param["default"] in frozenset((NoneStr, None, "None")): _param["default"] = None if _param["typ"] in frozenset(("Constant", "Str", "NamedConstant")): _param["typ"] = "object" if _param.get("typ") is None: return AnnAssign( annotation=Name("object", Load()), simple=1, target=Name(name, Store()), value=set_value(_param.get("default") or simple_types[_param["typ"]]), expr=None, expr_target=None, expr_annotation=None, ) elif needs_quoting(_param["typ"]): return AnnAssign( annotation=Name(_param["typ"], Load()) if _param["typ"] in simple_types else get_value(ast.parse(_param["typ"]).body[0]), simple=1, target=Name(name, Store()), value=set_value( quote(_param["default"]) if _param.get("default") else simple_types.get(_param["typ"]) ), expr=None, expr_target=None, expr_annotation=None, ) elif _param["typ"] in simple_types: return AnnAssign( annotation=Name(_param["typ"], Load()), simple=1, target=Name(name, Store()), value=set_value(_param.get("default") or simple_types[_param["typ"]]), expr=None, expr_target=None, expr_annotation=None, ) elif _param["typ"] == "dict" or _param["typ"].startswith("*"): return AnnAssign( annotation=set_slice(Name("dict", Load())), simple=1, target=Name(name, Store()), value=Dict(keys=[], values=_param.get("default", []), expr=None), expr=None, expr_target=None, expr_annotation=None, ) else: from doctrans.emitter_utils import ast_parse_fix annotation = ast_parse_fix(_param["typ"]) value = set_value(None) if "default" in _param: if ( isinstance(_param["default"], str) and len(_param["default"]) > 6 and _param["default"].startswith("```") and _param["default"].endswith("```") and _param["default"][3:-3] in frozenset(("None", "(None)")) ): value = set_value(None) else: try: parsed_default = ( set_value(_param["default"]) if ( _param["default"] is None or isinstance(_param["default"], (float, int, str)) ) and not isinstance(_param["default"], str) and not ( isinstance(_param["default"], str) and _param["default"][0] + _param["default"][-1] in frozenset(("()", "[]", "{}")) ) else ast.parse(_param["default"]) ) except SyntaxError: parsed_default = set_value("```{}```".format(_param["default"])) value = ( parsed_default.body[0].value if hasattr(parsed_default, "body") else parsed_default if "default" in _param else set_value(None) ) return AnnAssign( annotation=annotation, simple=1, target=Name(name, Store()), value=value, expr=None, expr_target=None, expr_annotation=None, )
def populate_files(tempdir, input_module_str=None): """ Populate files in the tempdir :param tempdir: Temporary directory :type tempdir: ```str``` :param input_module_str: Input string to write to the input_filename. If None, uses preset mock module. :type input_module_str: ```Optional[str]``` :returns: input filename, input str, expected_output :rtype: ```Tuple[str, str, str, Module]``` """ input_filename = os.path.join(tempdir, "input{extsep}py".format(extsep=extsep)) input_class_name = "Foo" input_class_ast = emit.class_( parse.function(deepcopy(method_adder_ast)), emit_call=False, class_name=input_class_name, ) input_module_ast = Module( body=[ input_class_ast, Assign(targets=[Name("input_map", Store())], value=Dict( keys=[set_value(input_class_name)], values=[Name(input_class_name, Load())], expr=None, ), expr=None, lineno=None, **maybe_type_comment), Assign( targets=[Name("__all__", Store())], value=List( ctx=Load(), elts=[set_value(input_class_name), set_value("input_map")], expr=None, ), expr=None, lineno=None, **maybe_type_comment), ], type_ignores=[], stmt=None, ) input_module_str = input_module_str or to_code(input_module_ast) # expected_output_class_str = ( # "class FooConfig(object):\n" # ' """\n' # " The amazing Foo\n\n" # " :cvar a: An a. Defaults to 5\n" # ' :cvar b: A b. Defaults to 16"""\n' # " a = 5\n" # " b = 16\n\n" # " def __call__(self):\n" # " self.a = 5\n" # " self.b = 16\n" # ) expected_class_ast = emit.class_( parse.function(deepcopy(method_adder_ast)), emit_call=True, class_name="{input_class_name}Config".format( input_class_name=input_class_name), ) with open(input_filename, "wt") as f: f.write(input_module_str) return input_filename, input_module_ast, input_class_ast, expected_class_ast
def param2ast(param): """ Converts a param to an AnnAssign :param param: Name, dict with keys: 'typ', 'doc', 'default' :type param: ```Tuple[str, dict]``` :returns: AST node for assignment :rtype: ```Union[AnnAssign, Assign]``` """ name, _param = param del param if _param.get("typ") is None and "default" in _param and "[" not in _param: _param["typ"] = type(_param["default"]).__name__ if "default" in _param: if isinstance(_param["default"], (Constant, Str)): _param["default"] = get_value(_param["default"]) if _param["default"] in none_types: _param["default"] = None if _param["typ"] in frozenset(("Constant", "Str", "NamedConstant")): _param["typ"] = "object" elif _param["default"] == NoneStr: _param["default"] = None if _param.get("typ") is None: return AnnAssign( annotation=Name("object", Load()), simple=1, target=Name(name, Store()), value=set_value(_param.get("default")), expr=None, expr_target=None, expr_annotation=None, ) # return Assign( # annotation=None, # simple=1, # targets=[Name(name, Store())], # value=set_value(_param.get("default")), # expr=None, # expr_target=None, # expr_annotation=None, # **maybe_type_comment # ) elif needs_quoting(_param["typ"]): return AnnAssign( annotation=Name(_param["typ"], Load()) if _param["typ"] in simple_types else get_value(ast.parse(_param["typ"]).body[0]), simple=1, target=Name(name, Store()), value=set_value( quote(_param["default"]) if _param.get("default") else simple_types.get(_param["typ"]) ), expr=None, expr_target=None, expr_annotation=None, ) elif _param["typ"] in simple_types: return AnnAssign( annotation=Name(_param["typ"], Load()), simple=1, target=Name(name, Store()), value=set_value( None if _param.get("default") == NoneStr else (_param.get("default") or simple_types[_param["typ"]]) ), expr=None, expr_target=None, expr_annotation=None, ) elif _param["typ"] == "dict" or _param["typ"].startswith("*"): return AnnAssign( annotation=set_slice(Name("dict", Load())), simple=1, target=Name(name, Store()), value=Dict(keys=[], values=_param.get("default", []), expr=None), expr=None, expr_target=None, expr_annotation=None, ) else: return _generic_param2ast((name, _param))
def dictconst(self, tree): from ast import Dict, Load keys = tree[0::2] values = tree[1::2] return Dict(keys, values)
def visit_Call(self, node): if isinstance(node.func, Name) and node.func.id == TARGET_CLASS: keys = [Constant(value=keyword.arg) for keyword in node.keywords] values = [keyword.value for keyword in node.keywords] return Dict(keys, values) return node
def factor(self): self.dbg_msg("factor") tok = self.peek() if tok.kind == EzhilToken.LPAREN: lparen_tok = self.dequeue() val = self.expr() if self.dequeue().kind != EzhilToken.RPAREN: raise SyntaxError("Missing Parens " + str(self.last_token())) elif tok.kind == EzhilToken.NUMBER: tok_num = self.dequeue() [l, c] = tok_num.get_line_col() val = Number(tok.val, l, c, self.debug) elif tok.kind == EzhilToken.LOGICAL_NOT: tok_not = self.dequeue() [l, c] = tok_not.get_line_col() val = UnaryExpr(self.expr(), tok_not, l, c, self.debug) self.dbg_msg("completed parsing unary expression" + str(val)) elif tok.kind == EzhilToken.ID: tok_id = self.dequeue() [l, c] = tok_id.get_line_col() val = Identifier(tok.val, l, c, self.debug) ptok = self.peek() self.dbg_msg("factor: " + str(ptok) + " / " + str(tok)) if (ptok.kind == EzhilToken.LPAREN): ## function call [l, c] = ptok.get_line_col() vallist = self.valuelist() val = ExprCall(val, vallist, l, c, self.debug) elif (ptok.kind == EzhilToken.LSQRBRACE): ## indexing a array type variable or ID [l, c] = ptok.get_line_col() ## replace with a call to __getitem__ exp = self.factor() if (hasattr(exp, '__getitem__')): VL2 = ValueList([val, exp[0]], l, c, self.debug) else: # when exp is a expression VL2 = ValueList([val, exp], l, c, self.debug) val = ExprCall(Identifier("__getitem__", l, c), VL2, l, c, self.debug) for itr in range(1, len(exp)): VL2 = ValueList([val, exp[itr]], l, c, self.debug) val = ExprCall(Identifier("__getitem__", l, c), VL2, l, c, self.debug) #raise ParseException("array indexing implemented"+str(ptok)); elif (ptok.kind == EzhilToken.LCURLBRACE): val = None raise ParseException("dictionary indexing implemented" + str(ptok)) elif tok.kind == EzhilToken.STRING: str_tok = self.dequeue() [l, c] = str_tok.get_line_col() val = String(tok.val, l, c, self.debug) elif tok.kind in EzhilToken.ADDSUB: unop = self.dequeue() [l, c] = unop.get_line_col() val = Expr(Number(0), unop, self.term(), l, c, self.debug) elif tok.kind == EzhilToken.LCURLBRACE: # creating a list/dictionary expression dict_start = self.dequeue() val = Dict() while (True): if (self.peek().kind == EzhilToken.RCURLBRACE): break exprkey = self.expr() tok_colon = self.match(EzhilToken.COLON) exprval = self.expr() val.update({exprkey: exprval}) if self.debug: print(self.peek().__class__, self.peek()) if (self.peek().kind == EzhilToken.RCURLBRACE): break else: assert (self.peek().kind == EzhilToken.COMMA) self.dequeue() assert (self.peek().kind == EzhilToken.RCURLBRACE) list_end = self.dequeue() elif tok.kind == EzhilToken.LSQRBRACE: # creating a list/array expression list_start = self.dequeue() val = Array() while (True): if (self.peek().kind == EzhilToken.RSQRBRACE): break exprval = self.expr() val.append(exprval) if self.debug: print(self.peek().__class__, self.peek()) if (self.peek().kind == EzhilToken.RSQRBRACE): break else: assert (self.peek().kind == EzhilToken.COMMA) self.dequeue() assert (self.peek().kind == EzhilToken.RSQRBRACE) list_end = self.dequeue() else: raise ParseException("Expected Number, found something " + str(tok)) self.dbg_msg("factor-returning: " + str(val)) return val