Exemple #1
0
    def exact_src_imp(tree, src, indexes, line_lengths):
        all_child_pos = sorted(indexer.collect(tree))
        start_index = linear_index(line_lengths(), *all_child_pos[0])

        last_child_index = linear_index(line_lengths(), *all_child_pos[-1])

        first_successor_index = indexes()[min(
            indexes().index(last_child_index) + 1,
            len(indexes()) - 1)]

        for end_index in range(last_child_index, first_successor_index + 1):

            prelim = src[start_index:end_index]
            prelim = _transforms.get(type(tree), "%s") % prelim

            if isinstance(tree, stmt):
                prelim = prelim.replace("\n" + " " * tree.col_offset, "\n")

            if isinstance(tree, list):
                prelim = prelim.replace("\n" + " " * tree[0].col_offset, "\n")

            try:
                if isinstance(tree, expr):
                    x = "(" + prelim + ")"
                else:
                    x = prelim
                import ast
                parsed = ast.parse(x)
                if unparse(parsed).strip() == unparse(tree).strip():
                    return prelim

            except SyntaxError as e:
                pass
        raise ExactSrcException()
Exemple #2
0
    def exact_src_imp(tree, src, indexes, line_lengths):
        all_child_pos = sorted(indexer.collect(tree))
        start_index = linear_index(line_lengths(), *all_child_pos[0])

        last_child_index = linear_index(line_lengths(), *all_child_pos[-1])

        first_successor_index = indexes()[min(indexes().index(last_child_index)+1, len(indexes())-1)]

        for end_index in range(last_child_index, first_successor_index+1):

            prelim = src[start_index:end_index]
            prelim = _transforms.get(type(tree), "%s") % prelim


            if isinstance(tree, stmt):
                prelim = prelim.replace("\n" + " " * tree.col_offset, "\n")

            if isinstance(tree, list):
                prelim = prelim.replace("\n" + " " * tree[0].col_offset, "\n")

            try:
                if isinstance(tree, expr):
                    x = "(" + prelim + ")"
                else:
                    x = prelim
                import ast
                parsed = ast.parse(x)
                if unparse(parsed).strip() == unparse(tree).strip():
                    return prelim

            except SyntaxError as e:
                pass
        raise ExactSrcException()
def my_macro2(tree, **kw):
    assert unparse(tree).strip() == "\n".join([
        "@middle", "@inner", "def run():", "    x = 10", "    x = (x + 1)",
        "    x = (x + 1)", "    x = (x + 1)", "    x = (x + 1)", "    return x"
    ]), unparse(tree)

    return tree
def my_macro(tree, **kw):
    assert unparse(tree).strip() == "\n".join([
        "@inner", "def run():", "    x = 10", "    x = (x + 1)", "    return x"
    ]), unparse(tree)

    b = tree.body
    tree.body = [b[0], b[1], b[1], b[1], b[1], b[2]]
    return tree
Exemple #5
0
    def testBuildOpsList(self):
        """
        Proper jump tables get built for multiple try/except blocks.
        """
        input = ast.parse(sampleAst1).body
        output = buildOperationsDAG(input)
        self.assertEqual(
            [[unparse(line[0]).strip()] + list(line[1:]) for line in output],
            [
                ["resolve(r, BytesObject(contents))", None, None, None, None],
                ["ruv.magic_fsClose(vat, f)", output[0], None, None, None],
                ["smash(r, StrObject((u'libuv error: %s' % err)))",
                 None, None, None, None],
                ["ruv.magic_fsClose(vat, f)", output[2], None, None, None],
                ["readLoop(f, buf)", output[1], output[3], "contents", "err"],
                ['smash(r, StrObject((u"Couldn\'t open file fount: %s" % err)))',
                 None, None, None, None],
                ['ruv.magic_fsOpen(vat, path, os.O_RDONLY, 0)', output[4],
                 output[5], "f", "err"],
                ['0', output[6], None, 'f', None]
            ])

        input = ast.parse(sampleAst2).body
        output = buildOperationsDAG(input)
        self.assertEqual(
            [[unparse(line[0]).strip()] + list(line[1:]) for line in output],
            [
                ["ioC()", None, None, None, None],
                ["ioB()", output[0], None, None, None],
                ["ioA()", output[1], None, None, None],
                ["io9()", output[1], None, None, None],
                ["io8()", output[2], output[3], None, "err3"],
                ["io7()", output[4], output[3], None, "err3"],
                ["io6()", output[5], None, None, None],
                ["io5()", output[0], None, None, None],
                ["io4()", output[0], output[7], None, "err2"],
                ["io3()", output[8], None, None, None],
                ["io2()", output[6], output[9], "y", "err1"],
                ["io1()", output[10], output[9], "x", "err1"],
                ["1", output[11], None, "x", None]
            ])

        input = ast.parse(sampleAst3).body
        output = buildOperationsDAG(input)
        self.assertEqual(
            [[unparse(line[0]).strip()] + list(line[1:]) for line in output],
            [
                ["io6()", None, None, None, None],
                ["io5()", output[0], None, None, None],
                ["io4()", output[0], output[1], None, "err2"],
                ["io3()", output[0], output[1], None, "err2"],
                ["io2()", output[2], output[3], "y", "err1"],
                ["io1()", output[4], output[3], "x", "err1"],
                ["io0()", output[5], output[1], None, "err2"]
            ])
def my_macro(tree, **kw):
    assert unparse(tree).strip() == "\n".join([
    "@inner",
    "def run():",
    "    x = 10",
    "    x = (x + 1)",
    "    return x"]), unparse(tree)

    b = tree.body
    tree.body = [b[0], b[1], b[1], b[1], b[1], b[2]]
    tree.decorator_list = [hq[added_decorator]] + tree.decorator_list
    return tree
def my_macro2(tree, **kw):
    assert unparse(tree).strip() == "\n".join([
    "@middle",
    "@added_decorator",
    "@inner",
    "def run():",
    "    x = 10",
    "    x = (x + 1)",
    "    x = (x + 1)",
    "    x = (x + 1)",
    "    x = (x + 1)",
    "    return x"]), unparse(tree)

    return tree
Exemple #8
0
def dbg_expr(tree):
    ln = q[u[tree.lineno]] if hasattr(tree, "lineno") else q[None]
    filename = hq[callsite_filename()]
    return q[dbgprint_expr(u[unparse(tree)],
                           ast_literal[tree],
                           filename=ast_literal[filename],
                           lineno=ast_literal[ln])]
Exemple #9
0
    def export_transformed(self, code, tree, module_name, file_name):

        new_path = os.path.join(self.root, self.directory,
                                os.path.relpath(file_name, self.root))

        with open(new_path, "w") as f:
            f.write(unparse(tree))
Exemple #10
0
    def export_transformed(self, tree, module_name, file_name):

        new_path = os.path.join(
            self.root,
            self.directory,
            os.path.relpath(file_name, self.root)
        )

        with open(new_path, "w") as f:
            f.write(unparse(tree))
Exemple #11
0
 def transform(tree, **kw):
     if type(tree) is Call and type(tree.func) is Name and tree.func.id == pname:
         names = [q[u[unparse(node)]] for node in tree.args]  # x --> "x"; (1 + 2) --> "(1 + 2)"; ...
         names = Tuple(elts=names, lineno=tree.lineno, col_offset=tree.col_offset)
         values = Tuple(elts=tree.args, lineno=tree.lineno, col_offset=tree.col_offset)
         tree.args = [names, values]
         # can't use inspect.stack in the printer itself because we want the line number *before macro expansion*.
         tree.keywords += [keyword(arg="filename", value=q[__file__]),
                           keyword(arg="lineno", value=(q[u[tree.lineno]] if hasattr(tree, "lineno") else q[None]))]
         tree.func = q[ast_literal[p]]
     return tree
def _test_block_signals_or_raises(block_body, args, syntaxname, asserter):
    if not block_body:
        return []  # pragma: no cover, cannot happen through the public API.
    first_stmt = block_body[0]

    # Note we want the line number *before macro expansion*, so we capture it now.
    ln = q[u[first_stmt.lineno]] if hasattr(first_stmt, "lineno") else q[None]
    filename = hq[callsite_filename()]

    # with test_raises(exctype, message):
    # TODO: Python 3.8+: ast.Constant, no ast.Str
    if len(args) == 2 and type(args[1]) is Str:
        exctype, message = args
    # with test_raises(exctype):
    elif len(args) == 1:
        exctype = args[0]
        message = q[None]
    else:
        assert False, 'Expected `with {stx}(exctype):` or `with {stx}(exctype, message):`'.format(
            stx=syntaxname)

    # Before we edit the tree, get the source code in its pre-transformation
    # state, so we can include that into the test failure message.
    sourcecode = unparse(block_body)

    gen_sym = dyn.gen_sym
    testblock_function_name = gen_sym("test_block")
    #def unpythonic_assert_raises(exctype, sourcecode, thunk, *, filename, lineno, message=None):

    thetest = q[(ast_literal[asserter])(ast_literal[exctype],
                                        u[sourcecode],
                                        name[testblock_function_name],
                                        filename=ast_literal[filename],
                                        lineno=ast_literal[ln],
                                        message=ast_literal[message])]
    with q as newbody:

        def _insert_funcname_here_(
        ):  # no env needed, since `the[]` is not meaningful here.
            ...

        ast_literal[thetest]
    thefunc = newbody[0]
    thefunc.name = testblock_function_name
    thefunc.body = block_body
    return newbody
def test_expr(tree):
    # Note we want the line number *before macro expansion*, so we capture it now.
    ln = q[u[tree.lineno]] if hasattr(tree, "lineno") else q[None]
    filename = hq[callsite_filename()]
    asserter = hq[unpythonic_assert]

    # test[expr, message]  (like assert expr, message)
    # TODO: Python 3.8+: ast.Constant, no ast.Str
    if type(tree) is Tuple and len(
            tree.elts) == 2 and type(tree.elts[1]) is Str:
        tree, message = tree.elts
    # test[expr]  (like assert expr)
    else:
        message = q[None]

    # Before we edit the tree, get the source code in its pre-transformation
    # state, so we can include that into the test failure message.
    sourcecode = unparse(tree)

    gen_sym = dyn.gen_sym
    envname = gen_sym("e")  # for injecting the captured value

    # Handle the `the[...]` mark, if any.
    tree, the_exprs = _transform_important_subexpr.recurse_collect(
        tree, envname=envname)
    if len(the_exprs) > 1:
        assert False, "test[]: At most one `the[...]` may appear in expr"  # pragma: no cover
    if len(the_exprs) == 0 and type(
            tree) is Compare:  # inject the implicit the[] on the LHS
        tree.left = _inject_value_recorder(envname, tree.left)

    # We delay the execution of the test expr using a lambda, so
    # `unpythonic_assert` can get control first before the expr runs.
    #
    # Also, we need the lambda for passing in the value capture environment
    # for the `the[]` mark, anyway.
    func_tree = q[lambda _: ast_literal[
        tree]]  # create the function that takes in the env
    func_tree.args.args[0] = arg(
        arg=envname)  # inject the gensymmed parameter name

    return q[(ast_literal[asserter])(u[sourcecode],
                                     ast_literal[func_tree],
                                     filename=ast_literal[filename],
                                     lineno=ast_literal[ln],
                                     message=ast_literal[message])]
def _test_expr_signals_or_raises(tree, syntaxname, asserter):
    ln = q[u[tree.lineno]] if hasattr(tree, "lineno") else q[None]
    filename = hq[callsite_filename()]

    # test_signals[exctype, expr, message]
    # TODO: Python 3.8+: ast.Constant, no ast.Str
    if type(tree) is Tuple and len(
            tree.elts) == 3 and type(tree.elts[2]) is Str:
        exctype, tree, message = tree.elts
    # test_signals[exctype, expr]
    elif type(tree) is Tuple and len(tree.elts) == 2:
        exctype, tree = tree.elts
        message = q[None]
    else:
        assert False, "Expected one of {stx}[exctype, expr], {stx}[exctype, expr, message]".format(
            stx=syntaxname)

    return q[(ast_literal[asserter])(ast_literal[exctype],
                                     u[unparse(tree)],
                                     lambda: ast_literal[tree],
                                     filename=ast_literal[filename],
                                     lineno=ast_literal[ln],
                                     message=ast_literal[message])]
Exemple #15
0
def indexer(tree, collect, **kw):
    try:
        unparse(tree)
        collect((tree.lineno, tree.col_offset))
    except Exception, e:
        pass
Exemple #16
0
def printcode(tree, expand_macros, **kw):
    expanded_tree = expand_macros(tree)
    print(unparse(expanded_tree))
    return expanded_tree
def test_block(block_body, args):
    if not block_body:
        return []  # pragma: no cover, cannot happen through the public API.
    first_stmt = block_body[0]

    # Note we want the line number *before macro expansion*, so we capture it now.
    ln = q[u[first_stmt.lineno]] if hasattr(first_stmt, "lineno") else q[None]
    filename = hq[callsite_filename()]
    asserter = hq[unpythonic_assert]

    # with test(message):
    # TODO: Python 3.8+: ast.Constant, no ast.Str
    if len(args) == 1 and type(args[0]) is Str:
        message = args[0]
    # with test:
    elif len(args) == 0:
        message = q[None]
    else:
        assert False, 'Expected `with test:` or `with test(message):`'

    # Before we edit the tree, get the source code in its pre-transformation
    # state, so we can include that into the test failure message.
    sourcecode = unparse(block_body)

    gen_sym = dyn.gen_sym
    envname = gen_sym("e")  # for injecting the captured value
    testblock_function_name = gen_sym("test_block")

    # Handle the `the[...]` mark, if any.
    block_body, the_exprs = _transform_important_subexpr.recurse_collect(
        block_body, envname=envname)
    if len(the_exprs) > 1:
        assert False, "test[]: At most one `the[...]` may appear in a `with test` block"  # pragma: no cover

    thetest = q[(ast_literal[asserter])(u[sourcecode],
                                        name[testblock_function_name],
                                        filename=ast_literal[filename],
                                        lineno=ast_literal[ln],
                                        message=ast_literal[message])]
    with q as newbody:

        def _insert_funcname_here_(_insert_envname_here_):
            ...

        ast_literal[thetest]
    thefunc = newbody[0]
    thefunc.name = testblock_function_name
    thefunc.args.args[0] = arg(
        arg=envname)  # inject the gensymmed parameter name

    # Handle the return statement.
    #
    # We just check if there is at least one; if so, we don't need to do
    # anything; the returned value is what the test should return to the
    # asserter.
    for stmt in block_body:
        if type(stmt) is Return:
            retval = stmt.value
            if len(the_exprs) == 0 and type(retval) is Compare:
                # inject the implicit the[] on the LHS
                retval.left = _inject_value_recorder(envname, retval.left)
    else:
        # When there is no return statement at the top level of the `with test` block,
        # we inject a `return True` to satisfy the test when the function returns normally.
        with q as thereturn:
            return True
        block_body.append(thereturn)

    thefunc.body = block_body

    return newbody
Exemple #18
0
def preprocess(tree, **kw):
    #print(tree)
    if tree.name in container['config']:
        tree = transform.recurse(tree, ctx=tree.name)  #, init_ctx=tree.name
        print(unparse(tree))
    return tree
Exemple #19
0
    def testOpsToCallbacks(self):
        """
        Op lists are converted to callback lists properly.
        """
        def flattenOps(ops):
            return [[unparse(line.base).strip(), line.successName,
                     line.successExpr and unparse(line.successExpr).strip(),
                     line.successCB, line.failName,
                     line.failExpr and unparse(line.failExpr).strip(),
                     line.failCB] for line in ops]
        input = ast.parse(sampleAst1).body
        initialState, output = opsToCallbacks(buildOperationsDAG(input))
        self.assertEqual(initialState.keys(), ['f'])
        self.assertEqual([unparse(v) for v in initialState.values()], ['0'])
        self.assertEqual(
            flattenOps(output),
            [['ruv.magic_fsOpen.callbackType', "f", "readLoop(f, buf)",
              output[1], "err",
              'smash(r, StrObject((u"Couldn\'t open file fount: %s" % err)))',
              None],
             ['readLoop.callbackType', "contents", "ruv.magic_fsClose(vat, f)",
              output[3], "err", "ruv.magic_fsClose(vat, f)", output[2]],
             ['ruv.magic_fsClose.callbackType', None,
              "smash(r, StrObject((u'libuv error: %s' % err)))", None, None,
              None, None],
             ['ruv.magic_fsClose.callbackType', None,
              "resolve(r, BytesObject(contents))", None, None, None, None]])

        input = ast.parse(sampleAst2).body
        initialState, output = opsToCallbacks(buildOperationsDAG(input))
        self.assertEqual(initialState.keys(), ['x'])
        self.assertEqual([unparse(v) for v in initialState.values()], ['1'])
        self.assertEqual(
            flattenOps(output),
            [['io1.callbackType', 'x', 'io2()', output[1], 'err1', 'io3()',
              output[2]],
             ['io2.callbackType', 'y', 'io6()', output[5], 'err1', 'io3()',
              output[2]],
             ['io3.callbackType', None, 'io4()', output[3], None, None,
              None],
             ['io4.callbackType', None, 'ioC()', None, 'err2', 'io5()',
              output[4]],
             ['io5.callbackType', None, 'ioC()', None, None, None, None],
             ['io6.callbackType', None, 'io7()', output[6], None, None,
              None],
             ['io7.callbackType', None, 'io8()', output[7], 'err3', 'io9()',
              output[8]],
             ['io8.callbackType', None, 'ioA()', output[9], 'err3', 'io9()',
              output[8]],
             ['io9.callbackType', None, 'ioB()', output[10], None, None,
              None],
             ['ioA.callbackType', None, 'ioB()', output[10], None, None,
              None],
             ['ioB.callbackType', None, 'ioC()', None, None, None, None]])

        input = ast.parse(sampleAst3).body
        initialState, output = opsToCallbacks(buildOperationsDAG(input))
        self.assertEqual(initialState, {})
        self.assertEqual(
            flattenOps(output),
            [['io0.callbackType', None, 'io1()', output[1], 'err2', 'io5()',
              output[5]],
             ['io1.callbackType', 'x', 'io2()', output[2], 'err1', 'io3()',
              output[3]],
             ['io2.callbackType', 'y', 'io4()', output[4], 'err1', 'io3()',
              output[3]],
             ['io3.callbackType', None, 'io6()', None, 'err2', 'io5()',
              output[5]],
             ['io4.callbackType', None, 'io6()', None, 'err2', 'io5()',
              output[5]],
             ['io5.callbackType', None, 'io6()', None, None, None, None]])
Exemple #20
0
 def flattenOps(ops):
     return [[unparse(line.base).strip(), line.successName,
              line.successExpr and unparse(line.successExpr).strip(),
              line.successCB, line.failName,
              line.failExpr and unparse(line.failExpr).strip(),
              line.failCB] for line in ops]
Exemple #21
0
def indexer(tree, collect, **kw):
    try:
        unparse(tree)
        collect((tree.lineno, tree.col_offset))
    except Exception, e:
        pass