Ejemplo n.º 1
0
 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)
Ejemplo n.º 2
0
def getGlobalVariable(name):  # _lambda_0
    return Assign(
        targets=[
            Name(
                id=name + '_locals',
                ctx=Store()
            )
        ],
        value=Dict(keys=[], values=[]), type_comment=None)
Ejemplo n.º 3
0
 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
Ejemplo n.º 4
0
    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)))
Ejemplo n.º 6
0
    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
Ejemplo n.º 7
0
    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,
            ),
        )
Ejemplo n.º 8
0
    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],
                        ),
                    ),
                ],
            )
Ejemplo n.º 9
0
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,
        )
Ejemplo n.º 10
0
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
Ejemplo n.º 11
0
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))
Ejemplo n.º 12
0
 def dictconst(self, tree):
     from ast import Dict, Load
     keys = tree[0::2]
     values = tree[1::2]
     return Dict(keys, values)
Ejemplo n.º 13
0
 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
Ejemplo n.º 14
0
    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