Beispiel #1
0
 def _if_gt(value):
     if value >= 0:
         comparators = [Constant(value=value, kind=None)]
     else:
         comparators = [
             UnaryOp(
                 op=USub(),
                 operand=Constant(value=abs(value), kind=None),
             ),
         ]
     return [
         If(
             test=Compare(
                 left=Call(
                     func=Name(id='int', ctx=Load()),
                     args=[Name(id='value', ctx=Load())],
                     keywords=[],
                 ),
                 ops=[Gt()],
                 comparators=comparators,
             ),
             body=[
                 Return(value=Constant(value=False, kind=None), ),
             ],
             orelse=[],
         )
     ]
Beispiel #2
0
 def _if_pattern(self, pattern):
     self.imported.add('re')
     # fix known ietf regex use
     pattern = pattern.replace('\\p{N}\\p{L}', '\\w')
     return [
         If(
             test=UnaryOp(
                 op=Not(),
                 operand=Call(
                     func=Attribute(
                         value=Name(id='re', ctx=Load()),
                         attr='match',
                         ctx=Load(),
                     ),
                     args=[
                         Constant(value=pattern, kind=None),
                         Name(id='value', ctx=Load()),
                         Attribute(
                             value=Name(id='re', ctx=Load()),
                             attr='UNICODE',
                             ctx=Load(),
                         ),
                     ],
                     keywords=[],
                 ),
             ),
             body=[
                 Return(value=Constant(value=False, kind=None), ),
             ],
             orelse=[],
         ),
     ]
Beispiel #3
0
def test_ast_tree_edit_distance() -> None:
    node1 = ast.parse("a=1")
    node2 = ast.parse("a=1")
    assert ast_tree_edit_distance(node1, node2) == 0
    node2 = ast.parse("b=1")
    assert ast_tree_edit_distance(node1, node2) == 1
    node2 = ast.parse("b=2")
    assert ast_tree_edit_distance(node1, node2) == 1.5
    node1 = Assign(
        targets=[Name(id="a", ctx=Store())],
        value=Constant(value=1, kind=None),
        type_comment=None,
    )
    node2 = Assign(
        targets=[Name(id="a", ctx=Store())],
        value=Constant(value=1, kind=None),
        type_comment=None,
    )
    assert ast_tree_edit_distance(node1, node2) == 0
    node1 = ast.parse("")
    node2 = ast.parse("")
    assert ast_tree_edit_distance(node1, node2) == 0
    node1 = ast.parse("a")
    node2 = ast.parse("a")
    assert ast_tree_edit_distance(node1, node2) == 0
    node1 = Expr(Name("a", Load()))
    node2 = Expr(Name("a", Load()))
    assert ast_tree_edit_distance(node1, node2) == 0
    node1 = Name("a", Load())
    node2 = Name("a", Load())
    assert ast_tree_edit_distance(node1, node2) == 0
Beispiel #4
0
 def load_helpers(self) -> Iterable[stmt]:
     helpers = []
     if self.track_import_call:
         helpers.append(
             lineinfo(
                 make_assign(
                     [lineinfo(ast.Name("<strict-modules>", ast.Store()))],
                     lineinfo(
                         ast.Subscript(
                             lineinfo(ast.Name("<fixed-modules>", ast.Load())),
                             lineinfo(ast.Index(lineinfo(Constant("__strict__")))),
                             ast.Load(),
                         )
                     ),
                 )
             )
         )
         helpers.append(
             lineinfo(
                 make_assign(
                     [lineinfo(ast.Name("<track-import-call>", ast.Store()))],
                     lineinfo(
                         ast.Subscript(
                             lineinfo(ast.Name("<strict-modules>", ast.Load())),
                             lineinfo(
                                 ast.Index(lineinfo(Constant("track_import_call")))
                             ),
                             ast.Load(),
                         )
                     ),
                 )
             ),
         )
     return helpers
Beispiel #5
0
 def visit_Name(self, node):
     if isinstance(node.ctx, Store):
         return self.make_node(
             node, "storeName", values=[copy_loc(node, Constant(value=node.id))]
         )
     else:
         return self.make_node(
             node, "name", values=[copy_loc(node, Constant(value=node.id))]
         )
Beispiel #6
0
def d_identifier_or_constant(t):
    '''    identifier_or_constant      :    "[a-zA-Z0-9]+" instmode
    '''    #                     you need to use double quotes here!
    if t[0].lower() == "true" or t[0] == "1":
        return Constant("True", instmode=t[1])
    elif t[0].lower() == "false" or t[0] == "0":
        return Constant("False", instmode=t[1])
    else:
        return Identifier(t[0], instmode=t[1])
def getScopeTracer(file_name, method_name, id):  # name = _lamba_0
    return Expr(
        value=Call(
            func=Attribute(
                value=Name(id='Tracer', ctx=Load()),
                attr='traceScope', ctx=Load()
            ), args=[
                Constant(value=str(file_name), kind=None),
                Constant(value=str(id), kind=None),
                Name(id=method_name + '_locals', ctx=Load())
            ], keywords=[]
        )
    )
Beispiel #8
0
    def visit_FunctionDef(self, node, drop_decorator=False):
        if node.args.posonlyargs:
            raise WormSyntaxError(
                "Worm does not support positional only arguments.", at=get_loc(self.filename, node)
            )

        if node.args.kwonlyargs:
            raise WormSyntaxError(
                "Worm does not support keyword only arguments.", at=get_loc(self.filename, node)
            )

        args = copy_loc(
            node, List(elts=list(map(self.visit_arg, node.args.args)), ctx=Load())
        )
        defaults = copy_loc(
            node, List(elts=list(map(self.visit, node.args.defaults)), ctx=Load())
        )

        if len(node.body) > 0 and is_docstring(node.body[0]):
            d, *body = node.body
            docstring = d.value
        else:
            docstring = Constant(None)
            body = node.body

        func = self.make_node(
            node,
            "funcDef",
            values=[
                copy_loc(node, Constant(node.name)),
                args,
                defaults,
                self.make_node(
                    node,
                    "block",
                    values=[
                        copy_loc(
                            node,
                            List(elts=list(map(self.visit, body)), ctx=Load()),
                        )
                    ],
                ),
                node.returns or copy_loc(node, Constant(None)),
                docstring,
            ],
        )

        if drop_decorator:
            return func
        else:
            return reduce(compose_dec, reversed(node.decorator_list), func)
Beispiel #9
0
def _make_coverage_dummy_expr(macronode):
    """Force expression `macronode` to be reported as covered by coverage tools.

    This facilitates "deleting" expression nodes by `return None` from a macro.
    Since an expression slot in the AST cannot be empty, we inject a dummy node
    that evaluates to `None`.

    `macronode` is the macro invocation node to copy source location info from.
    """
    # TODO: inject the macro name for human-readability
    # We inject a lambda and an immediate call to it, because a constant `None`,
    # if it appears alone in an `ast.Expr`, is optimized away by CPython.
    # We must set location info manually, because we run after `expand`.
    non = copy_location(Constant(value=None), macronode)
    lam = copy_location(
        Lambda(args=arguments(posonlyargs=[],
                              args=[],
                              vararg=None,
                              kwonlyargs=[],
                              kw_defaults=[],
                              kwarg=None,
                              defaults=[]),
               body=non), macronode)
    call = copy_location(Call(func=lam, args=[], keywords=[]), macronode)
    return Done(call)
    def visit_Module(self, node):
        logging.info("Adding " + str(len(self.globalvars)) +
                     " global variables, " + str(len(self.methods)) + " methods")
        node_body = node.body
        node.body = []
        for n in node_body:
            if type(n) is ast.ImportFrom or type(n) is ast.Import:
                node.body.append(n)
                node_body.remove(n)

        node.body.append(
            Import(names=[alias(name='sys', asname=None)])
        )
        node.body.append(Expr(value=Call(func=Attribute(
            value=Attribute(value=Name(id='sys', ctx=Load()),
                            attr='path', ctx=Load()),
            attr='append',
            ctx=Load()),
            args=[Constant(value=path_to_tracer, kind=None)],
            keywords=[]))
        )
        node.body.append(Import(names=[alias(name='Tracer', asname=None)]))
        for globalvar in self.globalvars:
            node.body.append(globalvar)
        for method in self.methods:
            node.body.append(method)
        node.body.extend(node_body)
        return node
def getTracer(file_name, arg_name, id):
    return Expr(
        value=Call(
            func=Attribute(
                value=Name(id='Tracer', ctx=Load()),
                attr='trace', ctx=Load()),
            args=[
                Constant(value=str(file_name), kind=None),
                Constant(value=str(id), kind=None),
                Constant(value=str(arg_name), kind=None),
                Name(id=arg_name, ctx=Load()),
                
            ],
            keywords=[]
        )
    )
def getLambdaMethod(methodname, body, args_node, file, id):  # methodname = _lambda_0
    global lambdaID
    fullbody = []
    fullbody.extend(getTracers(file, args_node, id))
    fullbody.append(getScopeTracer(file, methodname, id))
    fullbody.append(
        Return(
            value=Call(
                func=Name(id='eval', ctx=Load()),
                args=[
                    Constant(value=to_source(body), kind=None),
                    Call(
                        func=Name(id='locals', ctx=Load()),
                        args=[],
                        keywords=[]),
                    Name(id=methodname + '_locals', ctx=Load())],
                keywords=[]
            )
        )
    )
    return FunctionDef(
        name=methodname + '_return',
        args=args_node,
        body=fullbody,
        decorator_list=[],
        returns=None,
        type_comment=None)
Beispiel #13
0
    def ID(self, tree):
        if hasattr(tree, "value") and tree.value in ("true", "false"):
            from ast import Constant

            return Constant("true" == tree.value)

        return astlib.name(tree.value)
Beispiel #14
0
def _add_coverage_dummy_node(tree, macronode, macroname):
    '''Force `macronode` to be reported as covered by coverage tools.

    The dummy node will be injected to `tree`. The `tree` must appear in a
    position where `ast.NodeTransformer.visit` may return a list of nodes.

    `macronode` is the macro invocation node to copy source location info from.
    `macroname` is included in the dummy node, to ease debugging.
    '''
    # `macronode` itself might be macro-generated. In that case don't bother.
    if not hasattr(macronode, 'lineno') and not hasattr(
            macronode, 'col_offset'):
        return tree
    if tree is None:
        tree = []
    elif isinstance(tree, AST):
        tree = [tree]
    # The dummy node must actually run to get coverage, so an `ast.Pass` won't do.
    # It must *do* something, or CPython optimizes it away, so an `ast.Expr` won't do.
    # We must set location info manually, because we run after `expand`.
    v = copy_location(
        Constant(
            value=f"source line {macronode.lineno} invoked macro {macroname}"),
        macronode)
    t = copy_location(Name(id="_mcpyrate_coverage", ctx=Store()), macronode)
    dummy = copy_location(Assign(targets=[t], value=v), macronode)
    tree.insert(
        0, Done(dummy)
    )  # mark as Done so any expansions further out won't mess this up.
    return tree
Beispiel #15
0
    def _expand(self, syntax, target, macroname, tree, kw=None):
        """
        Transform `target` node, replacing it with the expansion result of
        aplying the named macro on the proper node and recursively treat the
        expansion as well.
        """
        macro = self.bindings[macroname]
        kw = kw or {}
        kw.update({
            'syntax': syntax,
            'to_source': unparse,
            'expand_macros': self.visit
        })
        expansion = _apply_macro(macro, tree, kw)

        if syntax == 'block':
            # I'm not sure why is all this mess
            #
            # Strategy 1: Make the last line cover the whole block.
            # Result: Covers the "with document" line, but not the last one.
            # copy_location(expansion[-1], target)
            #
            # Strategy 2: Make the second line cover the whole block.
            # Result: Covers all, unless the block is just 2 lines.
            # copy_location(expansion[1], target) # Lo mejor para largo > 2
            #
            # Strategy 3: Insert a second dummy line covering the whole block.
            # Result: Works
            dummy = Expr(value=Call(func=Name(id="id", ctx=Load()), args=[Constant(value="bogus", kind=None)], keywords=[]),
                         lineno=target.lineno)
            copy_location(dummy, target)
            expansion.insert(1, dummy)
        expansion = self._visit_expansion(expansion, target)
        return expansion
Beispiel #16
0
def test_ast_equal() -> None:
    a = Name(id="print", ctx=Load())
    b = Name(id="print", ctx=Load())
    assert ast_deep_equal(a, b)

    a = Expr(value=Call(
        func=Name(id="print", ctx=Load()),
        args=[Constant(value="hello, world")],
        keywords=[],
    ))
    b = Expr(value=Call(
        func=Name(id="print", ctx=Load()),
        args=[Constant(value="hello, world")],
        keywords=[],
    ))
    assert ast_deep_equal(a, b)
    def _attr_lookup(self, attr, value):
        if "__" not in attr:
            return Compare(
                left=Attribute(value=Name(id="self", **self.file),
                               attr=attr,
                               **self.file),
                ops=[Eq()],
                comparators=[self.build_expression(value)],
                **self.file,
            )

        attr, lookup = attr.split("__", 1)

        if lookup == "isnull":
            return Compare(
                left=Attribute(value=Name(id="self", **self.file),
                               attr=attr,
                               **self.file),
                ops=[Is() if value else IsNot()],
                comparators=[
                    Constant(value=None, **self.file)
                    # Name(id="None", **self.file)
                ],
                **self.file,
            )

        if lookup == "exact":
            return self._attr_lookup(attr, value)

        raise ValueError("Unhandled attr lookup")
Beispiel #18
0
def set_value(value, kind=None):
    """
    Creates a Constant or a Str depending on Python version in use

    :param value: AST node
    :type value: ```Any```

    :param kind: AST node
    :type kind: ```Optional[Any]```

    :return: Probably a string, but could be any constant value
    :rtype: ```Union[Constant, Str, NameConstant]```
    """
    if (
        value is not None
        and isinstance(value, str)
        and len(value) > 2
        and value[0] + value[-1] in frozenset(('""', "''"))
    ):
        value = value[1:-1]
    return (
        Constant(kind=kind, value=value, constant_value=None, string=None)
        if PY_GTE_3_8
        else (
            Str(s=value, constant_value=None, string=None)
            if isinstance(value, str)
            else Num(n=value, constant_value=None, string=None)
            if not isinstance(value, bool) and isinstance(value, (int, float, complex))
            else NameConstant(value=value, constant_value=None, string=None)
        )
    )
Beispiel #19
0
    def visit_FunctionDef(self, node):
        # if there is at least one decorator, it may be a worm one
        if node.decorator_list:
            # get the Worm AST
            try:
                undecorated_func = RewriteWorm(self.filename).visit_FunctionDef(node, drop_decorator=True)
            except Exception as e:
                msg = Constant(*e.args)
                lambda_worm_func = make_node(self.filename, node, "invalidNode", values=[msg])
            else:
                undecorated_func.decorator_list = []
                lambda_worm_func = make_lambda(undecorated_func)

            decorators = make_list(
                node.decorator_list[0], node.decorator_list
            )
            apply = make_apply_decorator(decorators, lambda_worm_func)
            node.decorator_list = [apply]

        if len(node.body) > 0 and is_docstring(node.body[0]):
            docstring, *body = node.body
            node.body = [docstring, *map(self.visit, body)]
        else:
            node.body = list(map(self.visit, node.body))

        return node
Beispiel #20
0
 def _pattern(pattern):
     left, right = pattern
     if left in ("[]", "_"):
         right = e(f"lambda : {right}")
     else:
         right = e(f"lambda {left} : {right}")
     left = Constant(left)
     return Tuple(elts=[left, right], ctx=Load())
Beispiel #21
0
    def visit_arg(self, node):
        params = [copy_loc(node, Constant(node.arg))]

        if node.annotation:
            annot = self.visit(node.annotation)
            if annot:
                params.append(annot)

        return self.make_node(node, "arg", values=params)
Beispiel #22
0
 def make_cached_property_init_decorator(
     self,
     scope_data: ClassScope,
     class_scope: SymbolScope[TVar, TScopeData],
 ) -> expr:
     return lineinfo(
         ast.Call(
             lineinfo(ast.Name("<init-cached-properties>", ast.Load())),
             [
                 lineinfo(
                     ast.Dict(
                         [
                             lineinfo(
                                 Constant(mangle_priv_name(name, [class_scope]))
                             )
                             for name in scope_data.cached_props
                         ],
                         [
                             lineinfo(
                                 ast.Tuple(
                                     [
                                         lineinfo(
                                             Constant(
                                                 mangle_priv_name(
                                                     self.mangle_cached_prop(name),
                                                     [class_scope],
                                                 )
                                             )
                                         ),
                                         lineinfo(Constant(value)),
                                     ],
                                     ast.Load(),
                                 )
                             )
                             for name, value in scope_data.cached_props.items()
                         ],
                     )
                 )
             ],
             [],
         )
     )
Beispiel #23
0
    def visit_Yield(self, node):
        existing_node = self.generic_visit(node)
        value = existing_node.value
        if value is None:
            if Constant is None:
                value = Name(id='None', ctx=Load())
            else:
                value = Constant(value=None)

        return Yield(value=self._create_bare_context_call(
            'yield_value', [value, Num(n=existing_node.lineno)]))
Beispiel #24
0
 def mutate(self, node, index):
     root, new = node_copy_tree(node, index)
     value = eval(new.value)
     if isinstance(value, bytes):
         value = b"coffeebad" + value
     else:
         value = "mutated string " + value
     value = Constant(value=value, kind="")
     value = unparse(value).strip()
     new.value = value
     yield root, new
Beispiel #25
0
 def test_get_value(self) -> None:
     """Tests get_value succeeds"""
     val = "foo"
     self.assertEqual(get_value(Str(s=val, constant_value=None, string=None)), val)
     self.assertEqual(
         get_value(Constant(value=val, constant_value=None, string=None)), val
     )
     self.assertIsInstance(get_value(Tuple(expr=None)), Tuple)
     self.assertIsInstance(get_value(Tuple(expr=None)), Tuple)
     self.assertIsNone(get_value(Name(None, None)))
     self.assertEqual(get_value(get_value(ast.parse("-5").body[0])), -5)
Beispiel #26
0
def _make_product(terms):
    """
    Return an AST expressing the product of all the terms.
    """
    if terms:
        product = terms[0]
        for term in terms[1:]:
            product = BinOp(left=product, op=Mult(), right=term)
        return product 
    else:
        return Constant(value=1)
Beispiel #27
0
 def visit_Assign(self, n: Assign) -> Union[Assign, Tuple[Assign, Expr]]:
     assert len(n.targets) == 1 and isinstance(n.targets[0], Name)
     print_str = Call(
         Attribute(
             Constant(value=colored(f"{n.targets[0].id} = {{}}", "red")),
             attr="format",
             ctx=Load(),
         ),
         args=[Name(n.targets[0].id, Load())],
         keywords=[],
     )
     return (n, self._fix_location(self._make_print([print_str]), n))
Beispiel #28
0
 def visit_Attribute(self, node):
     if isinstance(node.ctx, Load):
         return self.make_node(
             node,
             "getAttr",
             values=[
                 self.visit(node.value),
                 Constant(node.attr),
             ],
         )
     elif isinstance(node.ctx, Store):
         return self.make_node(
             node,
             "setAttr",
             values=[
                 self.visit(node.value),
                 Constant(node.attr),
             ],
         )
     else:
         raise NotImplementedError()
Beispiel #29
0
    def _make_print(self, ns: List[expr], prefix: str = None) -> Expr:
        # create the indent: ' ' * depth
        mul_by = Name(self._DEPTH_VAR, Load())
        indent = BinOp(Constant(" "), Mult(), mul_by)
        # if prefix is given, indent is: ' ' * (depth - len(prefix)) + prefix
        if prefix is not None:
            assert len(
                prefix
            ) <= self._INDENT, f"too long {prefix} for given indent {self._INDENT}"
            indent.right = BinOp(mul_by, Sub(), Constant(len(prefix)))
            indent = BinOp(indent, Add(), Constant(prefix))

        return Expr(
            Call(
                Name("print", Load()),
                args=cast(List[expr], [indent]) + ns,
                keywords=[
                    keyword("sep", Constant("")),
                    keyword("file",
                            Attribute(Name("sys", Load()), "stderr", Load())),
                ],
            ))
Beispiel #30
0
 def visit_Assign(self, node):
     self.generic_visit(node)
     if not all(isinstance(tgt, Name) for tgt in node.targets):
         return node
     names = List(elts=[Constant(value=tgt.id) for tgt in node.targets],
                  ctx=Load())
     values = List(
         elts=[Name(id=tgt.id, ctx=Load()) for tgt in node.targets],
         ctx=Load())
     return node, Expr(
         Call(func=Name(id="__assign__", ctx=Load()),
              args=[names, values],
              keywords=[]))