예제 #1
0
파일: stub.py 프로젝트: spaceone-dev/PPTT
def make_data_field(shape: GraphicFrame):
    if shape.has_text_frame:
        value = text_data_value
    elif shape.has_table:
        value = table_data_value
    elif shape.has_chart:
        value = CHART_DATA_TYPE_MAP.get(shape.chart.chart_type, chart_category_data_value)
    else:
        return None

    return AnnAssign(
        target=Name(id=name_to_slugify(shape.name), ctx=Store()),
        annotation=value,
        value=ast_default_field(None),
        simple=1,
    )
예제 #2
0
        def _generate_assignment((arg_name, arg_resource_handle)):
            # type: (Tuple[basestring, int]) -> If
            """
            We have a function that looks like:
            def do_something(param, model_=INJECTED):
                <...>

            We insert into its beginning a statement like
                ___INJECT_CONTEXT_INTERNAL_RESOURCES = ___INJECT_CONTEXT_INTERNAL.resources
                if model_ is INJECTED:
                    model_ = ___INJECT_CONTEXT_INTERNAL_RESOURCES[3]
                    if model is ___INJECT_CONTEXT_INTERNAL:    # means that no resource is available
                        ___INJECT_CONTEXT_INTERNAL_RESOURCES.flag_missing('model_')

            Code outside of this function sets a global variable _INJECTED__model to point at the right thing.
            """
            target_attribute = Subscript(
                value=Name(id=INTERNAL_RESOURCES_NAME, ctx=Load()),
                slice=Index(value=Num(n=arg_resource_handle)),
                ctx=Load())

            consequence = [
                Assign(targets=[Name(id=arg_name, ctx=Store())],
                       value=target_attribute),
                If(test=Compare(
                    left=Name(id=arg_name, ctx=Load()),
                    ops=[Is()],
                    comparators=[Name(id=INTERNAL_CONTEXT_NAME, ctx=Load())]),
                   body=[
                       Expr(value=Call(func=Attribute(value=Name(
                           id=INTERNAL_CONTEXT_NAME, ctx=Load()),
                                                      attr='flag_missing',
                                                      ctx=Load()),
                                       keywords=[],
                                       starargs=None,
                                       kwargs=None,
                                       args=[Str(s=arg_name)]))
                   ],
                   orelse=[])
            ]  # type: List[Union[Assign, If]

            return If(test=Compare(
                left=Name(id=arg_name, ctx=Load()),
                ops=[Is()],
                comparators=[default_nodes_mapping[arg_name]]),
                      body=consequence,
                      orelse=[])
    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 compile_extendsnode(self, srcnode, parent):
        if '$' in srcnode.href:
            value = _interpolated_str_to_ast_value(srcnode.href)
            parent.body.append(Assign(targets=[StoreName('__piglet_tmp')],
                                      value=value))
            loadcode = '__piglet_rt.load(__piglet_template, __piglet_tmp)\n'

        else:
            loadcode = ('__piglet_rt.load(__piglet_template, "{}")\n'
                        .format(srcnode.href))

        parent.body.extend(parse_and_strip(
            '__piglet_parent = {}'
            '__piglet_bases = [__piglet_parent] + __piglet_bases\n'
            .format(loadcode)))

        for n in srcnode.children:
            if isinstance(n, im.BlockNode):
                self.compile_blockreplacenode(n, parent)
            elif isinstance(n, im.DefNode):
                self._compile(n, parent)

        block_ids = [make_block_name(n.name)
                     for n in srcnode.find(im.BlockNode)]

        parent_template_call = Call(
            func=LoadAttribute('__piglet_parent', '__piglet_root__'),
            args=[],
            starargs=None,
            kwargs=None,
            keywords=([keyword(arg='__piglet_bases',
                               value=LoadName('__piglet_bases'))] +
                      [keyword(arg=str(b), value=LoadName(str(b)))
                       for b in block_ids])
        )
        add_kwarg(parent_template_call, '__piglet_extra_blocks')

        if YieldFrom is not None:
            parent.body.append(
                Expr(value=YieldFrom(value=parent_template_call)))
        else:
            loopvar = self.unique_id('loop')
            parent.body.append(
                For(target=Name(id=loopvar, ctx=Store()),
                    iter=parent_template_call,
                    body=[Expr(value=Yield(Name(id=loopvar, ctx=Load())))],
                    orelse=[]))
예제 #5
0
    def visit_Module(self, n: Module) -> Module:
        """
        Adds:
        1. a global "__depth". TODO: make it a thread-local variable, instead of a global.
        2. "import sys"
        """
        self.generic_visit(n)
        # add it afterwards: so this variable doesn't get traced itself :)
        n.body.insert(
            0,
            self._fix_location(
                Assign([Name(self._DEPTH_VAR, Store())], Constant(0)),
                n.body[0]))

        # add the import
        n.body.insert(0, self._fix_location(Import([alias("sys")]), n.body[0]))
        return n
예제 #6
0
파일: debugger.py 프로젝트: legalian/xaxiom
		def visit_Return(self,node:ast.Return):
			if self.hot == None or (not self.hotHasReturnCheck and self.funcNames[self.hot] not in self.exitpatterns): return node
			# print("Assign: ",self.funcNames[self.hot])
			sin = [
				Assign(targets=[Name(id='_dbg_ret_var', ctx=Store())], value=node.value),
				Return(value=Name(id='_dbg_ret_var', ctx=Load()))
			]
			if self.hotHasReturnCheck:
				expattern = self.funcparams[self.hot]
				sin.insert(1,Expr(value=Call(func=Name(id='_dbgExit', ctx=Load()), args=[Name(id=pn+'_dbg_str_var_'+str(self.hot),ctx=Load()) for pn in expattern]+[Name(id='_dbg_ret_var', ctx=Load())], keywords=[])))
			if self.funcNames[self.hot] in self.exitpatterns:
				expattern = self.exitpatterns[self.funcNames[self.hot]]
				sin.insert(1,Expr(value=Call(func=Name(id='_dbgExit_'+self.funcNames[self.hot],ctx=Load()), args=[Name(id=pn+'_dbg_str_var_'+str(self.hot),ctx=Load()) for pn in expattern]+[Name(id='_dbg_ret_var', ctx=Load())], keywords=[])))
			for s in sin:
				ast.copy_location(s, node)
				ast.fix_missing_locations(s)
			return sin
예제 #7
0
    def visit_comp(self, node):
        """ Find all functions that are called multiple times with the same
         arguments as we will replace them with one variable
        """
        call_visitor = DuplicateCallFinder()
        call_visitor.visit(node)

        # Keep track of what calls we need to replace using a stack so we
        # support nested comprehensions
        self.calls_to_replace_stack.append(call_visitor.duplicate_calls)

        # Visit children of this list comprehension and replace calls
        self.generic_visit(node)

        # Gather the existing if statements as we need to move them to the
        # last comprehension generator (or there will be issues looking up
        # identifiers)
        existing_ifs = []
        for generator in node.generators:
            existing_ifs += generator.ifs
            generator.ifs = []

        # Create a new for loop for each function call result that we want
        # to alias and add it to the list comprehension
        for call in call_visitor.duplicate_calls:
            new_comprehension = comprehension(
                # Notice that we're storing (Store) the result of the call
                # instead of loading it (Load)
                target=Name(
                    id=OptimizeComprehensions._identifier_from_Call(call),
                    ctx=Store()),
                iter=List(elts=[call], ctx=Load()),
                ifs=[],
                is_async=0,
            )
            # Add linenos and other things the compile needs to node
            fix_missing_locations(new_comprehension)
            node.generators.append(new_comprehension)

        node.generators[-1].ifs = existing_ifs

        # Make sure we clear the calls to replace so we don't replace other
        # calls outside of the scope of this current list comprehension
        self.calls_to_replace_stack.pop()
        return node
예제 #8
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
예제 #9
0
    def test_gen_with_imports_from_file(self) -> None:
        """Tests `gen` with `imports_from_file`"""

        output_filename = os.path.join(
            self.tempdir,
            "test_gen_with_imports_from_file_output{extsep}py".format(
                extsep=extsep),
        )
        with patch("sys.stdout",
                   new_callable=StringIO), patch("sys.stderr",
                                                 new_callable=StringIO):
            self.assertIsNone(
                gen(
                    name_tpl="{name}Config",
                    input_mapping="gen_test_module.input_map",
                    imports_from_file="gen_test_module",
                    emit_name="class",
                    parse_name="infer",
                    output_filename=output_filename,
                    emit_call=True,
                    emit_default_doc=False,
                ))
        with open(output_filename, "rt") as f:
            gen_ast = ast.parse(f.read())
        run_ast_test(
            self,
            gen_ast=gen_ast,
            gold=Module(
                body=[
                    _import_star_from_input_ast,
                    self.expected_class_ast,
                    Assign(targets=[Name("__all__", Store())],
                           value=List(
                               ctx=Load(),
                               elts=[set_value("FooConfig")],
                               expr=None,
                           ),
                           expr=None,
                           lineno=None,
                           **maybe_type_comment),
                ],
                type_ignores=[],
                stmt=None,
            ),
        )
예제 #10
0
파일: py_converter.py 프로젝트: jiajuns/tvm
 def visit_ref_write(self, write: Expr):
     """For writing refs, we wrap the update in a thunk
     (returning an empty tuple to match Relay's semantics)
     that we execute at the right time. This ensures such assignments
     can be properly nested, since assignments are statements
     in Python but expressions in Relay"""
     ref, ref_defs = self.visit(write.ref)
     val, val_defs = self.visit(write.value)
     thunk_name = self.generate_function_name("_ref_write_thunk")
     thunk = self.create_def(
         thunk_name,
         [],
         ref_defs + val_defs + [
             Assign([ast.Attribute(ref, "value", Store())], val),
             Return(self.create_call("_container.tuple_object", [])),
         ],
     )
     return (self.create_call(thunk_name, []), [thunk])
예제 #11
0
    def test_param2ast_with_wrapped_default(self) -> None:
        """Check that `param2ast` behaves correctly with a wrapped default"""

        run_ast_test(
            self,
            param2ast(
                ("zion", {"typ": None, "default": set_value(NoneStr)}),
            ),
            gold=AnnAssign(
                annotation=Name("object", Load()),
                simple=1,
                target=Name("zion", Store()),
                value=set_value(None),
                expr=None,
                expr_target=None,
                expr_annotation=None,
            ),
        )
예제 #12
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,
            ),
        )
예제 #13
0
    def test_param2ast_with_assign(self) -> None:
        """Check that `param2ast` behaves correctly with a non annotated (typeless) input"""

        run_ast_test(
            self,
            param2ast(
                ("zion", {"typ": None}),
            ),
            gold=AnnAssign(
                annotation=Name("object", Load()),
                simple=1,
                target=Name("zion", Store()),
                value=set_value(None),
                expr=None,
                expr_target=None,
                expr_annotation=None,
            ),
        )
예제 #14
0
    def test_find_in_ast(self) -> None:
        """Tests that `find_in_ast` successfully finds nodes in AST"""

        run_ast_test(
            self,
            find_in_ast("ConfigClass.dataset_name".split("."), class_ast),
            AnnAssign(
                annotation=Name(
                    "str",
                    Load(),
                ),
                simple=1,
                target=Name("dataset_name", Store()),
                value=set_value("mnist"),
                expr=None,
                expr_target=None,
                expr_annotation=None,
            ),
        )
    def compile_importnode(self, srcnode, parent):

        assign = Assign(targets=[Name(id=str(srcnode.alias), ctx=Store())],
                        value=Call(func=Attribute(value=Name(id='__piglet_rt',
                                                             ctx=Load()),
                                                  attr='load',
                                                  ctx=Load()),
                                   args=[Name(id='__piglet_template', ctx=Load()),
                                         Str(s=srcnode.href)],
                                   starargs=None,
                                   kwargs=None,
                                   keywords=[]))
        assign = self.annotate_runtime_errors(assign, srcnode)

        container = self.get_func(parent)
        if container.name == '__piglet_root__':
            self.module.body.insert(self.module.body.index(container), assign)
        else:
            container.body.append(assign)
예제 #16
0
파일: logic.py 프로젝트: Croolman/arcor2
def program_src(type_defs: TypesDict, project: CProject, scene: CScene, add_logic: bool = True) -> str:

    tree = empty_script_tree(project.id, add_main_loop=add_logic)

    # get object instances from resources object
    main = find_function("main", tree)
    last_assign = find_last_assign(main)
    for obj in scene.objects:
        add_import(tree, "object_types." + humps.depascalize(obj.type), obj.type, try_to_import=False)
        last_assign += 1
        main.body.insert(last_assign, object_instance_from_res(obj.name, obj.id, obj.type))

    # TODO temporary solution - should be (probably) handled by plugin(s)
    import json

    # TODO should we put there even unused constants?
    for const in project.constants:
        val = json.loads(const.value)

        aval: Optional[expr] = None

        if isinstance(val, (int, float)):
            aval = Num(n=val, kind=None)
        elif isinstance(val, bool):
            aval = NameConstant(value=val, kind=None)
        elif isinstance(val, str):
            aval = Str(s=val, kind="")

        if not aval:
            raise Arcor2Exception(f"Unsupported constant type ({const.type}) or value ({val}).")

        last_assign += 1
        main.body.insert(
            last_assign,
            Assign(  # TODO use rather AnnAssign?
                targets=[Name(id=const.name, ctx=Store())], value=aval, type_comment=None
            ),
        )

    if add_logic:
        add_logic_to_loop(type_defs, tree, scene, project)

    return SCRIPT_HEADER + tree_to_str(tree)
예제 #17
0
 def test_emit_arg(self) -> None:
     """ Tests that `arg` is emitted from `emit_arg` """
     self.assertIsInstance(
         class_with_method_and_body_types_ast.body[1].args.args[1], arg)
     self.assertIsInstance(
         emit_arg(
             class_with_method_and_body_types_ast.body[1].args.args[1]),
         arg)
     assign = Assign(targets=[Name("yup", Store())],
                     value=set_value("nup"),
                     expr=None,
                     **maybe_type_comment)
     gen_ast = emit_arg(assign)
     self.assertIsInstance(gen_ast, arg)
     run_ast_test(
         self,
         gen_ast=gen_ast,
         gold=set_arg("yup"),
     )
예제 #18
0
def merge_assignment_lists(node, name, unique_sort=True):
    """
    Merge multiple same-name lists within the body of a node into one, e.g., if you have multiple ```__all__```

    :param node: AST node with a '.body'
    :type node: ```Union[Module, ClassDef, FunctionDef, If, Try, While, With, AsyncFor, AsyncFunctionDef, AsyncWith,
                         ExceptHandler, Expression, For, IfExp, Interactive, Lambda ]```

    :param name: Name to match (matches against `id` field of `Name`)
    :type name: ```str```

    :param unique_sort: Whether to ensure its unique + sorted
    :type unique_sort: ```bool```
    """
    asses = tuple(get_ass_where_name(node, name))

    # if len(asses) < 2: return

    # Could extract the `AnnAssign` stuff I suppose…

    del_ass_where_name(node, name)
    elts = chain.from_iterable(
        map(
            attrgetter("elts"),
            asses,
        )
    )
    node.body.append(
        Assign(
            targets=[Name("__all__", Store())],
            value=List(
                ctx=Load(),
                elts=sorted(frozenset(elts), key=get_value)
                if unique_sort
                else list(elts),
                expr=None,
            ),
            expr=None,
            lineno=None,
            **maybe_type_comment
        )
    )
예제 #19
0
    def test_param2ast_with_bad_default(self) -> None:
        """Check that `param2ast` behaves correctly with a bad default"""

        run_ast_test(
            self,
            param2ast(
                (
                    "stateful_metrics",
                    {"typ": "NoneType", "default": "the `Model`'s metrics"},
                ),
            ),
            gold=AnnAssign(
                annotation=Name("NoneType", Load()),
                simple=1,
                target=Name("stateful_metrics", Store()),
                value=set_value("```the `Model`'s metrics```"),
                expr=None,
                expr_annotation=None,
                expr_target=None,
            ),
        )
예제 #20
0
def object_instance_from_res(object_name: str, object_id: str,
                             cls_name: str) -> AnnAssign:

    try:
        is_valid_identifier(object_name)
    except Arcor2Exception as e:
        raise Arcor2Exception(f"Object name {object_name} invalid. {str(e)}")

    try:
        is_valid_type(cls_name)
    except Arcor2Exception as e:
        raise Arcor2Exception(f"Class name {cls_name} invalid. {str(e)}")

    return AnnAssign(
        target=Name(id=object_name, ctx=Store()),
        annotation=Name(id=cls_name, ctx=Load()),
        value=Subscript(value=get_name_attr("res", "objects"),
                        slice=Index(value=Str(s=object_id, kind="")),
                        ctx=Load()),
        simple=1,
    )
예제 #21
0
def value(classdef, **kw):
    '''
    Quick definition of singleton values a-la Scala. Example:

        @value
        class superman:
            name = 'Klark'
            surname = 'Kent'
            def completename(): return name + ' ' + surname

        assert(not isinstance(superman, type))
        assert(isinstance(superman, object))
        assert(superman.completename() == 'Klark Kent')
    '''
    symbols = _gather_symbols(classdef)
    baked_class = _IntoValueTransformer(symbols).visit(classdef)
    replacement = Assign(targets=[Name(id=baked_class.name, ctx=Store())],
                         value=Call(func=Name(id=baked_class.name, ctx=Load()),
                                    args=[],
                                    keywords=[]))
    return [baked_class, replacement]
예제 #22
0
    def func(tree, **kw):
        if _is_pattern_match_stmt(tree):
            modified = set()
            matcher = build_matcher(tree.value.left, modified)
            # lol random names for hax
            with q as assignment:
                xsfvdy = ast(matcher)

            statements = [
                assignment,
                Expr(q(xsfvdy._match_value(ast(tree.value.right))))
            ]

            for var_name in modified:
                statements.append(
                    Assign([Name(var_name, Store())],
                           q(xsfvdy.get_var(u(var_name)))))

            return statements
        else:
            return tree
예제 #23
0
def getLocalsFunction(var_name):  # _lambda_0
    return FunctionDef(
        name=var_name,
        args=arguments(
            posonlyargs=[],
            args=[arg(arg='locls', annotation=None, type_comment=None)],
            vararg=None,
            kwonlyargs=[],
            kw_defaults=[],
            kwarg=None,
            defaults=[]),
        body=[
            Global(names=[var_name + '_locals']),
            Assign(
                targets=[Name(id=var_name + '_locals', ctx=Store())],
                value=Name(id='locls', ctx=Load()),
                type_comment=None),
            Return(value=Name(id=var_name + '_return', ctx=Load()))
        ],
        decorator_list=[],
        returns=None,
        type_comment=None)
예제 #24
0
    def convert(self, prog: Expr):
        """This method converts the passed Relay expression into a Python
        AST object with equivalent semantics.

        The Python AST can be executed using exec(); it can be turned
        into text and inspected using astor.
        """
        optimized = self.optimize(prog)

        # start with conversion prelude (imports) and convert global defs
        body = []
        body += PROLOGUE
        body += self.convert_module()

        prog_body, extra_defs = self.visit(optimized)
        body += extra_defs

        # we finally must assign the final expression to the output var
        # so it can be read after running EXEC
        body.append(Assign([Name(OUTPUT_VAR_NAME, Store())], prog_body))

        return ast.fix_missing_locations(ast.Module(body=body))
예제 #25
0
def new_object_type(parent: ObjectTypeMeta, child: ObjectTypeMeta) -> AST:

    assert parent.type == child.base

    tree = Module(body=[], type_ignores=[])

    if parent.type in built_in_types_names():
        import_from = arcor2.object_types.abstract.__name__
    else:
        import_from = f".{humps.depascalize(parent.type)}"

    tree.body.append(
        ImportFrom(module=import_from,
                   names=[alias(name=parent.type, asname=None)],
                   level=0))

    c = ClassDef(
        name=child.type,
        bases=[get_name(parent.type)],
        keywords=[],
        body=[
            Assign(
                targets=[Name(id="_ABSTRACT", ctx=Store())],
                value=NameConstant(value=False, kind=None),
                type_comment=None,
            )
        ],
        decorator_list=[],
    )

    # TODO add docstring with description (if provided)
    c.body.append(Pass())

    tree.body.append(c)

    return tree
예제 #26
0
 def visit_Return(self, n: Return):
     """
     * Decrement the depth before exiting. We have to save the returned value into a temporary,
       and only then decrement; otherwise, if the return value itself is a Call, we lose the
       depth.
     """
     var = Assign([Name(self._RETURN_VAR, Store())], n.value)
     n.value = Name(self._RETURN_VAR, Load())
     return self._fix_location_all(
         [
             var,
             self._make_print(
                 [
                     self._parse_fstring(
                         colored(f"return {{{self._RETURN_VAR}}}",
                                 self.RETURN_COLOR))
                 ],
                 "< ",
             ),
             self._decrement_depth(),
             n,
         ],
         n,
     )
    def __init__(self, filename):
        self.filename = filename
        self.uniquec = defaultdict(count)
        self.src_root = None
        self.module = Module(
            body=[ImportFrom(module='piglet',
                             names=[
                                 alias(name='runtime', asname='__piglet_rt')],
                             level=0)]
        )

        # Store references to generated functions corresponding to nested
        # py:blocks to facilitate retro-fitting the necessary function
        # arguments up the call chain.
        self.block_chain = []

        self.module.body.extend([
            Assign(targets=[Name(id='Markup', ctx=Store())],
                   value=Attribute(value=Name(id='__piglet_rt', ctx=Load()),
                                   attr='Markup',
                                   ctx=Load())),
            Assign(targets=[StoreName('__piglet_rtdata')],
                   value=LoadAttribute('__piglet_rt', 'data'))
        ])
예제 #28
0
    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.
        """
        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]
        if isinstance(try_body[0], Expr) and isinstance(
                try_body[0].value, Str):
            # Move docstring back to top of function.
            new_node.body.insert(0, try_body.pop(0))

        # 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))
        if new_node.args.vararg is not None:
            new_node.body.append(
                self._trace_assignment(new_node.args.vararg, node.lineno))
        if new_node.args.kwarg is not None:
            new_node.body.append(
                self._trace_assignment(new_node.args.kwarg, node.lineno))

        if try_body:
            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
예제 #29
0
def document(sentences, **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(sentences)):
        s = sentences[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):  # pragma: no cover (Internal)
                # Note: The support for variables isn't currently used
                name = target.id
                is_attr = False
            elif isinstance(target, Attribute):
                name = target.attr
                is_attr = True
            else:
                # Just in case we put anything other than an attr/var assignment
                continue  # pragma: no cover (Internal)
            # 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 = ''
            post_hint = ''
            if isinstance(value, Num):
                type_hint = '[number={}]'.format(value.n)
            elif isinstance(value, UnaryOp) and isinstance(
                    value.operand, Num) and isinstance(value.op, USub):
                # -Num
                type_hint = '[number={}]'.format(-value.operand.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())
            elif isinstance(value, Attribute):
                # Used for the default options. I.e. GS.def_global_option
                val = eval(unparse(value))
                if isinstance(val, bool):
                    # Not used yet
                    type_hint = '[boolean={}]'.format(
                        str(val).lower())  # pragma: no cover (Internal)
                elif isinstance(val, (int, float)):
                    # Not used yet
                    type_hint = '[number={}]'.format(
                        val)  # pragma: no cover (Internal)
                elif isinstance(val, str):
                    type_hint = "[string='{}']".format(val)
                post_hint += '. Affected by global options'
            # 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:  # pragma: no cover (Internal)
                target = Name(id=doc_id, ctx=Store())
            # Reuse the s.value Str
            help_str = s.value
            help_str.s = type_hint + s.value.s.rstrip() + post_hint
            sentences[n] = Assign(targets=[target], value=help_str)
            # Copy the line number from the original docstring
            copy_location(target, s)
            copy_location(sentences[n], s)
        prev = s
    # Return the modified AST
    return sentences
예제 #30
0
파일: inline.py 프로젝트: binref/refinery
        def visit_FunctionDef(self, node: FunctionDef):
            nonlocal function_name, context
            if node is not function_head:
                return node
            function_body = []
            function_name = node.name
            function_args = [arg.arg for arg in node.args.args]
            inlined_start = 1

            if inspect.ismethod(method):
                inlined_start += 1

            iterator_name = function_args[inlined_start - 1]
            function_args[:inlined_start] = []
            arity = len(function_args)

            try:
                vararg = as_arg(node.args.vararg.arg)
            except Exception:
                if arity != len(inline_args):
                    raise ArgumentCountMismatch
            else:
                context[vararg] = inline_args[arity:]

            for name, value in zip(function_args, inline_args):
                targets = [Name(id=as_var(name), ctx=Store())]
                if isinstance(value, PassAsConstant):
                    context[as_var(name)] = value.value
                    continue
                if isinstance(value, (int, str, bytes)):
                    context[as_var(name)] = value
                    continue
                context[as_arg(name)] = value
                function_body.append(
                    Assign(targets=targets,
                           value=Call(func=Name(id='next', ctx=Load()),
                                      args=[Name(id=as_arg(name), ctx=Load())],
                                      keywords=[])))

            if node.args.vararg:
                name = node.args.vararg.arg
                function_body.append(
                    Assign(targets=[Name(id=as_var(name), ctx=Store())],
                           value=Call(
                               func=Name(id='tuple', ctx=Load()),
                               args=[
                                   GeneratorExp(
                                       elt=Call(func=Name(id='next',
                                                          ctx=Load()),
                                                args=[
                                                    Name(id=as_tmp(name),
                                                         ctx=Load())
                                                ],
                                                keywords=[]),
                                       generators=[
                                           comprehension(
                                               is_async=0,
                                               target=Name(id=as_tmp(name),
                                                           ctx=Store()),
                                               iter=Name(id=as_arg(name),
                                                         ctx=Load()),
                                               ifs=[])
                                       ])
                               ],
                               keywords=[])))

            function_body.extend(node.body)
            context[as_arg(iterator_name)] = iterator
            function_body = [
                For(target=Name(id=as_var(iterator_name), ctx=Store()),
                    iter=Name(id=as_arg(iterator_name), ctx=Load()),
                    body=function_body,
                    orelse=[])
            ]

            node.body = function_body
            node.args.args = [arg(arg=as_var('self'))]
            node.args.vararg = None
            node.decorator_list = []
            return node