Пример #1
0
 def test_fold_nonconst_list_to_tuple_in_comparisons(self):
     optimizer = AstOptimizer()
     tree = ast.parse("[a for a in b if a.c in [e, f]]")
     optimized = optimizer.visit(tree)
     self.assertEqual(
         to_expr(
             optimized.body[0].value.generators[0].ifs[0].comparators[0]),
         "(e, f)",
     )
Пример #2
0
    def test_rewrite_node(self):
        class TestRewriter(ASTRewriter):
            def visitName(self, node):
                if isinstance(node, ast.Name) and node.id == "z":
                    return ast.Name("foo", ast.Load())
                return node

        tree = ast.parse("x + y + z").body[0].value

        rewriter = TestRewriter()
        new_tree = rewriter.visit(tree)

        self.assertIsNotNone(new_tree)
        self.assertNotEqual(new_tree, tree, "tree should be rewritten")
        self.assertEqual(to_expr(new_tree), "x + y + foo")
        self.assertEqual(tree.left, new_tree.left,
                         "Unchanged nodes should be the same")
Пример #3
0
    def test_simple_examples(self):
        examples = [
            "a",
            "+a",
            "-a",
            "not a",
            "~a",
            "x is y",
            "x is not y",
            "x < y",
            "x > y",
            "x <= y",
            "x >= y",
            "x == y",
            "x != y",
            "None",
            "True",
            "False",
            "...",
            "42.0",
            "42j",
            "'abc'",
            "b'abc'",
            "foo.bar",
            "42 .bar",
            "42.0.bar" if sys.version_info >= (3, 8) else "42.0 .bar",
            "42j.bar" if sys.version_info >= (3, 8) else "42j .bar",
            "()",
            "(1,)",
            "(1, 2)",
            "[]",
            "[1, 2]",
            "{1, 2}",
            "{}",
            "{1: 2}",
            "{1: 2, 3: 4}",
            "a + 2",
            "a - 2",
            "a * 2",
            "a @ 2",
            "a / 2",
            "a % 2",
            "a << 2",
            "a >> 2",
            "a | 2",
            "a ^ 2",
            "a // 2",
            "a ** 2",
            "a[b]",
            "a[b:c]",
            "a[:c]",
            "a[b:]",
            "a[:]",
            "a[a:b:c]",
            "a[::c]",
            "a[b,]",
            "a[b, c:d]",
            "a(b)",
            "a(b, c)",
            "a(b, *c)",
            "a(b, *c, **foo)",
            "a(b=1)",
            "a(b=1, **foo)",
            "a(a, b=1, **foo)",
            "a(a, b=1, **foo)",
            "(yield)",
            "(yield 42)",
            "(yield from [])",
            "lambda: 42",
            "lambda a: 42",
            "lambda a=2: 42",
            "lambda*foo: 42",  # oddity of how CPython unparses this...
            "lambda a, *foo: 42",
            "lambda a, *, b=2: 42",
            "lambda*, b: 42",  # oddity of how CPython unparses this...
            "lambda*, b=2: 42",  # oddity of how CPython unparses this...
            "lambda x: (x, x)",
            "1 if True else 2",
            "f'foo'",
            "f'foo{bar}'",
            "f'foo{bar!a}'",
            # joined strings get combined
            ("f'foo{bar:N}'f'foo{bar:N}'", "f'foo{bar:N}foo{bar:N}'"),
            "f'foo{ {2: 3}}'",
            "f'{(lambda x: x)}'",
            "[x for x in abc]",
            "{x for x in abc}",
            "{x: y for x, y in abc}",
            "[x for x in abc if x]",
            "{x for x in abc if x}",
            "{x: y for x, y in abc if x}",
            "[x for x in abc for z in foo]",
            "{x for x in abc for z in foo}",
            "{x: y for x, y in abc for z in foo}",
            "[*abc]",
            "(x for x in y)",
        ]

        for example in examples:
            if isinstance(example, tuple):
                example, expected = example
            else:
                expected = example

            tree = ast.parse(example)
            self.assertEqual(expected, to_expr(tree.body[0].value))

            if sys.version_info >= (3, 7):
                # Make sure we match CPython's compilation too
                l = {}
                exec(
                    f"from __future__ import annotations\ndef f() -> {example}:\n    pass",
                    l,
                    l,
                )
                f = l["f"]
                self.assertEqual(expected, f.__annotations__["return"])
Пример #4
0
 def test_ast_optimizer_for(self):
     optimizer = AstOptimizer()
     tree = ast.parse("for x in [1,2,3]: pass")
     optimized = optimizer.visit(tree).body[0]
     self.assertEqual(to_expr(optimized.iter), "(1, 2, 3)")
Пример #5
0
 def test_ast_optimizer(self):
     cases = [
         ("+1", "1"),
         ("--1", "1"),
         ("~1", "-2"),
         ("not 1", "False"),
         ("not x is y", "x is not y"),
         ("not x is not y", "x is y"),
         ("not x in y", "x not in y"),
         ("~1.1", "~1.1"),
         ("+'str'", "+'str'"),
         ("1 + 2", "3"),
         ("1 + 3", "4"),
         ("'abc' + 'def'", "'abcdef'"),
         ("b'abc' + b'def'", "b'abcdef'"),
         ("b'abc' + 'def'", "b'abc' + 'def'"),
         ("b'abc' + --2", "b'abc' + 2"),
         ("--2 + 'abc'", "2 + 'abc'"),
         ("5 - 3", "2"),
         ("6 - 3", "3"),
         ("2 * 2", "4"),
         ("2 * 3", "6"),
         ("'abc' * 2", "'abcabc'"),
         ("b'abc' * 2", "b'abcabc'"),
         ("1 / 2", "0.5"),
         ("6 / 2", "3.0"),
         ("6 // 2", "3"),
         ("5 // 2", "2"),
         ("2 >> 1", "1"),
         ("6 >> 1", "3"),
         ("1 | 2", "3"),
         ("1 | 1", "1"),
         ("1 ^ 3", "2"),
         ("1 ^ 1", "0"),
         ("1 & 2", "0"),
         ("1 & 3", "1"),
         ("'abc' + 1", "'abc' + 1"),
         ("1 / 0", "1 / 0"),
         ("1 + None", "1 + None"),
         ("True + None", "True + None"),
         ("True + 1", "2"),
         ("(1, 2)", "(1, 2)"),
         ("(1, 2) * 2", "(1, 2, 1, 2)"),
         ("(1, --2, abc)", "(1, 2, abc)"),
         ("(1, 2)[0]", "1"),
         ("1[0]", "1[0]"),
         ("x[+1]", "x[1]"),
         ("(+1)[x]", "1[x]"),
         ("[x for x in [1,2,3]]", "[x for x in (1, 2, 3)]"),
         ("(x for x in [1,2,3])", "(x for x in (1, 2, 3))"),
         ("{x for x in [1,2,3]}", "{x for x in (1, 2, 3)}"),
         ("{x for x in [--1,2,3]}", "{x for x in (1, 2, 3)}"),
         ("{--1 for x in [1,2,3]}", "{1 for x in (1, 2, 3)}"),
         ("x in [1,2,3]", "x in (1, 2, 3)"),
         ("x in x in [1,2,3]", "x in x in (1, 2, 3)"),
         ("x in [1,2,3] in x", "x in [1, 2, 3] in x"),
     ]
     for inp, expected in cases:
         optimizer = AstOptimizer()
         tree = ast.parse(inp)
         optimized = to_expr(optimizer.visit(tree).body[0].value)
         self.assertEqual(expected, optimized, "Input was: " + inp)