Esempio n. 1
0
class NamedExprTest(CSTNodeTest):
    @data_provider(
        (
            {
                "node": cst.BinaryOperation(
                    left=cst.Name("a"),
                    operator=cst.MatrixMultiply(),
                    right=cst.Name("b"),
                ),
                "code": "a @ b",
                "parser": parse_expression_as(python_version="3.8"),
            },
            {
                "node": cst.SimpleStatementLine(
                    body=(
                        cst.AugAssign(
                            target=cst.Name("a"),
                            operator=cst.MatrixMultiplyAssign(),
                            value=cst.Name("b"),
                        ),
                    ),
                ),
                "code": "a @= b\n",
                "parser": parse_statement_as(python_version="3.8"),
            },
        )
    )
    def test_valid(self, **kwargs: Any) -> None:
        self.validate_node(**kwargs)

    @data_provider(
        (
            {
                "code": "a @ b",
                "parser": parse_expression_as(python_version="3.6"),
                "expect_success": True,
            },
            {
                "code": "a @ b",
                "parser": parse_expression_as(python_version="3.3"),
                "expect_success": False,
            },
            {
                "code": "a @= b",
                "parser": parse_statement_as(python_version="3.6"),
                "expect_success": True,
            },
            {
                "code": "a @= b",
                "parser": parse_statement_as(python_version="3.3"),
                "expect_success": False,
            },
        )
    )
    def test_versions(self, **kwargs: Any) -> None:
        if is_native() and not kwargs.get("expect_success", True):
            self.skipTest("parse errors are disabled for native parser")
        self.assert_parses(**kwargs)
Esempio n. 2
0
 def leave_BooleanOperation(
         self, original_node: cst.BooleanOperation,
         updated_node: cst.BooleanOperation) -> cst.BinaryOperation:
     if isinstance(updated_node.operator, self.match):
         return cst.BinaryOperation(left=updated_node.left,
                                    operator=self.replace(),
                                    right=updated_node.right,
                                    lpar=updated_node.lpar,
                                    rpar=updated_node.rpar)
     else:
         return updated_node
 def test_simple_expression(self) -> None:
     expression = parse_template_expression(
         "{a} + {b} + {c}",
         a=cst.Name("one"),
         b=cst.Name("two"),
         c=cst.BinaryOperation(
             lpar=(cst.LeftParen(),),
             left=cst.Name("three"),
             operator=cst.Multiply(),
             right=cst.Name("four"),
             rpar=(cst.RightParen(),),
         ),
     )
     self.assertEqual(
         self.code(expression), "one + two + (three * four)",
     )
Esempio n. 4
0
    def visit_ConcatenatedString(self, node: cst.ConcatenatedString) -> None:
        # Skip if our immediate parent is also a ConcatenatedString, since our parent
        # should've already reported this violation.
        if isinstance(self.context.node_stack[-2], cst.ConcatenatedString):
            return

        # collect nested ConcatenatedString nodes into a flat list from outer to
        # innermost children
        children: List[cst.ConcatenatedString] = []
        el = node
        while isinstance(el, cst.ConcatenatedString):
            children.append(el)
            # left cannot be a ConcatenatedString, only right can.
            el = el.right

        # Build up a replacement by starting with the innermost child
        replacement = children[-1].right
        for el in reversed(children):
            replacement = cst.BinaryOperation(
                left=el.left,  # left is never a ConcatenatedString
                operator=cst.Add(
                    whitespace_before=el.whitespace_between,
                    whitespace_after=cst.SimpleWhitespace(" "),
                ),
                right=replacement,
                lpar=el.lpar,
                rpar=el.rpar,
            )

        # A binary operation has a lower priority in the order-of-operations than an
        # implicitly concatenated string, so we need to make sure the replacement is
        # parenthesized to make our change safe.
        if not replacement.lpar:
            # There's a good chance that the formatting might be messed up by this, but
            # black should be able to sort it out when it gets run next time.
            #
            # Because of the changes needed (e.g. increased indentation of children),
            # it's not really sane/possible for us to format this any better.
            replacement = replacement.with_changes(lpar=[cst.LeftParen()],
                                                   rpar=[cst.RightParen()])

        self.report(node, replacement=replacement)
Esempio n. 5
0
class BinaryOperationTest(CSTNodeTest):
    @data_provider(
        (
            # Simple binary operations
            {
                "node":
                cst.BinaryOperation(cst.Name("foo"), cst.Add(),
                                    cst.Float("5.5")),
                "code":
                "foo + 5.5",
                "parser":
                parse_expression,
                "expected_position":
                None,
            },
            {
                "node":
                cst.BinaryOperation(cst.Name("foo"), cst.Subtract(),
                                    cst.Float("5.5")),
                "code":
                "foo - 5.5",
                "parser":
                parse_expression,
                "expected_position":
                None,
            },
            {
                "node":
                cst.BinaryOperation(cst.Name("foo"), cst.LeftShift(),
                                    cst.Integer("5")),
                "code":
                "foo << 5",
                "parser":
                parse_expression,
                "expected_position":
                None,
            },
            {
                "node":
                cst.BinaryOperation(cst.Name("foo"), cst.RightShift(),
                                    cst.Integer("5")),
                "code":
                "foo >> 5",
                "parser":
                parse_expression,
                "expected_position":
                None,
            },
            {
                "node":
                cst.BinaryOperation(cst.Name("foo"), cst.BitAnd(),
                                    cst.Name("bar")),
                "code":
                "foo & bar",
                "parser":
                parse_expression,
                "expected_position":
                None,
            },
            {
                "node":
                cst.BinaryOperation(cst.Name("foo"), cst.BitXor(),
                                    cst.Name("bar")),
                "code":
                "foo ^ bar",
                "parser":
                parse_expression,
                "expected_position":
                None,
            },
            {
                "node":
                cst.BinaryOperation(cst.Name("foo"), cst.BitOr(),
                                    cst.Name("bar")),
                "code":
                "foo | bar",
                "parser":
                parse_expression,
                "expected_position":
                None,
            },
            {
                "node":
                cst.BinaryOperation(cst.Name("foo"), cst.Multiply(),
                                    cst.Float("5.5")),
                "code":
                "foo * 5.5",
                "parser":
                parse_expression,
                "expected_position":
                None,
            },
            {
                "node":
                cst.BinaryOperation(cst.Name("foo"), cst.MatrixMultiply(),
                                    cst.Float("5.5")),
                "code":
                "foo @ 5.5",
                "parser":
                parse_expression,
                "expected_position":
                None,
            },
            {
                "node":
                cst.BinaryOperation(cst.Name("foo"), cst.Divide(),
                                    cst.Float("5.5")),
                "code":
                "foo / 5.5",
                "parser":
                parse_expression,
                "expected_position":
                None,
            },
            {
                "node":
                cst.BinaryOperation(cst.Name("foo"), cst.Modulo(),
                                    cst.Float("5.5")),
                "code":
                "foo % 5.5",
                "parser":
                parse_expression,
                "expected_position":
                None,
            },
            {
                "node":
                cst.BinaryOperation(cst.Name("foo"), cst.FloorDivide(),
                                    cst.Float("5.5")),
                "code":
                "foo // 5.5",
                "parser":
                parse_expression,
                "expected_position":
                None,
            },
            # Parenthesized binary operation
            {
                "node":
                cst.BinaryOperation(
                    lpar=(cst.LeftParen(), ),
                    left=cst.Name("foo"),
                    operator=cst.LeftShift(),
                    right=cst.Integer("5"),
                    rpar=(cst.RightParen(), ),
                ),
                "code":
                "(foo << 5)",
                "parser":
                parse_expression,
                "expected_position":
                None,
            },
            # Make sure that spacing works
            {
                "node":
                cst.BinaryOperation(
                    lpar=(cst.LeftParen(
                        whitespace_after=cst.SimpleWhitespace(" ")), ),
                    left=cst.Name("foo"),
                    operator=cst.Multiply(
                        whitespace_before=cst.SimpleWhitespace("  "),
                        whitespace_after=cst.SimpleWhitespace("  "),
                    ),
                    right=cst.Name("bar"),
                    rpar=(cst.RightParen(
                        whitespace_before=cst.SimpleWhitespace(" ")), ),
                ),
                "code":
                "( foo  *  bar )",
                "parser":
                parse_expression,
                "expected_position":
                CodeRange((1, 2), (1, 13)),
            },
        ))
    def test_valid(self, **kwargs: Any) -> None:
        self.validate_node(**kwargs)

    @data_provider((
        {
            "get_node": (lambda: cst.BinaryOperation(
                cst.Name("foo"),
                cst.Add(),
                cst.Name("bar"),
                lpar=(cst.LeftParen(), ),
            )),
            "expected_re":
            "left paren without right paren",
        },
        {
            "get_node": (lambda: cst.BinaryOperation(
                cst.Name("foo"),
                cst.Add(),
                cst.Name("bar"),
                rpar=(cst.RightParen(), ),
            )),
            "expected_re":
            "right paren without left paren",
        },
    ))
    def test_invalid(self, **kwargs: Any) -> None:
        self.assert_invalid(**kwargs)
Esempio n. 6
0
 def to_binary_operation_cst(left, right):
     return cst.BinaryOperation(left, node.operator, right=right)
Esempio n. 7
0
class SmallStatementTest(CSTNodeTest):
    @data_provider((
        # pyre-fixme[6]: Incompatible parameter type
        {
            "node": cst.Pass(),
            "code": "pass"
        },
        {
            "node": cst.Pass(semicolon=cst.Semicolon()),
            "code": "pass;"
        },
        {
            "node":
            cst.Pass(semicolon=cst.Semicolon(
                whitespace_before=cst.SimpleWhitespace("  "),
                whitespace_after=cst.SimpleWhitespace("    "),
            )),
            "code":
            "pass  ;    ",
            "expected_position":
            CodeRange((1, 0), (1, 4)),
        },
        {
            "node": cst.Continue(),
            "code": "continue"
        },
        {
            "node": cst.Continue(semicolon=cst.Semicolon()),
            "code": "continue;"
        },
        {
            "node":
            cst.Continue(semicolon=cst.Semicolon(
                whitespace_before=cst.SimpleWhitespace("  "),
                whitespace_after=cst.SimpleWhitespace("    "),
            )),
            "code":
            "continue  ;    ",
            "expected_position":
            CodeRange((1, 0), (1, 8)),
        },
        {
            "node": cst.Break(),
            "code": "break"
        },
        {
            "node": cst.Break(semicolon=cst.Semicolon()),
            "code": "break;"
        },
        {
            "node":
            cst.Break(semicolon=cst.Semicolon(
                whitespace_before=cst.SimpleWhitespace("  "),
                whitespace_after=cst.SimpleWhitespace("    "),
            )),
            "code":
            "break  ;    ",
            "expected_position":
            CodeRange((1, 0), (1, 5)),
        },
        {
            "node":
            cst.Expr(
                cst.BinaryOperation(cst.Name("x"), cst.Add(), cst.Name("y"))),
            "code":
            "x + y",
        },
        {
            "node":
            cst.Expr(
                cst.BinaryOperation(cst.Name("x"), cst.Add(), cst.Name("y")),
                semicolon=cst.Semicolon(),
            ),
            "code":
            "x + y;",
        },
        {
            "node":
            cst.Expr(
                cst.BinaryOperation(cst.Name("x"), cst.Add(), cst.Name("y")),
                semicolon=cst.Semicolon(
                    whitespace_before=cst.SimpleWhitespace("  "),
                    whitespace_after=cst.SimpleWhitespace("    "),
                ),
            ),
            "code":
            "x + y  ;    ",
            "expected_position":
            CodeRange((1, 0), (1, 5)),
        },
    ))
    def test_valid(self, **kwargs: Any) -> None:
        self.validate_node(**kwargs)
Esempio n. 8
0
class AugAssignTest(CSTNodeTest):
    @data_provider((
        # Simple assignment constructor case.
        {
            "node":
            cst.AugAssign(cst.Name("foo"), cst.AddAssign(), cst.Integer("5")),
            "code":
            "foo += 5",
            "parser":
            None,
            "expected_position":
            CodeRange((1, 0), (1, 8)),
        },
        {
            "node":
            cst.AugAssign(cst.Name("bar"), cst.MultiplyAssign(),
                          cst.Name("foo")),
            "code":
            "bar *= foo",
            "parser":
            None,
            "expected_position":
            None,
        },
        # Whitespace constructor test
        {
            "node":
            cst.AugAssign(
                target=cst.Name("foo"),
                operator=cst.LeftShiftAssign(
                    whitespace_before=cst.SimpleWhitespace("  "),
                    whitespace_after=cst.SimpleWhitespace("  "),
                ),
                value=cst.Integer("5"),
            ),
            "code":
            "foo  <<=  5",
            "parser":
            None,
            "expected_position":
            CodeRange((1, 0), (1, 11)),
        },
        # Simple assignment parser case.
        {
            "node":
            cst.SimpleStatementLine((cst.AugAssign(cst.Name("foo"),
                                                   cst.AddAssign(),
                                                   cst.Integer("5")), )),
            "code":
            "foo += 5\n",
            "parser":
            parse_statement,
            "expected_position":
            None,
        },
        {
            "node":
            cst.SimpleStatementLine((cst.AugAssign(cst.Name("bar"),
                                                   cst.MultiplyAssign(),
                                                   cst.Name("foo")), )),
            "code":
            "bar *= foo\n",
            "parser":
            parse_statement,
            "expected_position":
            None,
        },
        # Whitespace parser test
        {
            "node":
            cst.SimpleStatementLine((cst.AugAssign(
                target=cst.Name("foo"),
                operator=cst.LeftShiftAssign(
                    whitespace_before=cst.SimpleWhitespace("  "),
                    whitespace_after=cst.SimpleWhitespace("  "),
                ),
                value=cst.Integer("5"),
            ), )),
            "code":
            "foo  <<=  5\n",
            "parser":
            parse_statement,
            "expected_position":
            None,
        },
    ))
    def test_valid(self, **kwargs: Any) -> None:
        self.validate_node(**kwargs)

    @data_provider((
        {
            "get_node": (
                lambda: cst.AugAssign(
                    # pyre-ignore: Incompatible parameter type [6]
                    target=cst.BinaryOperation(
                        left=cst.Name("x"),
                        operator=cst.Add(),
                        right=cst.Integer("1"),
                    ),
                    operator=cst.Add(),
                    value=cst.Name("y"),
                )),
            "expected_re":
            ("Expected an instance of .*BaseAssignTargetExpression.*"),
        }, ))
    def test_invalid_types(self, **kwargs: Any) -> None:
        self.assert_invalid_types(**kwargs)
Esempio n. 9
0
class AnnAssignTest(CSTNodeTest):
    @data_provider((
        # Simple assignment creation case.
        {
            "node":
            cst.AnnAssign(cst.Name("foo"), cst.Annotation(cst.Name("str")),
                          cst.Integer("5")),
            "code":
            "foo: str = 5",
            "parser":
            None,
            "expected_position":
            CodeRange((1, 0), (1, 12)),
        },
        # Annotation creation without assignment
        {
            "node": cst.AnnAssign(cst.Name("foo"),
                                  cst.Annotation(cst.Name("str"))),
            "code": "foo: str",
            "parser": None,
            "expected_position": CodeRange((1, 0), (1, 8)),
        },
        # Complex annotation creation
        {
            "node":
            cst.AnnAssign(
                cst.Name("foo"),
                cst.Annotation(
                    cst.Subscript(
                        cst.Name("Optional"),
                        (cst.SubscriptElement(cst.Index(cst.Name("str"))), ),
                    )),
                cst.Integer("5"),
            ),
            "code":
            "foo: Optional[str] = 5",
            "parser":
            None,
            "expected_position":
            CodeRange((1, 0), (1, 22)),
        },
        # Simple assignment parser case.
        {
            "node":
            cst.SimpleStatementLine((cst.AnnAssign(
                target=cst.Name("foo"),
                annotation=cst.Annotation(
                    annotation=cst.Name("str"),
                    whitespace_before_indicator=cst.SimpleWhitespace(""),
                ),
                equal=cst.AssignEqual(),
                value=cst.Integer("5"),
            ), )),
            "code":
            "foo: str = 5\n",
            "parser":
            parse_statement,
            "expected_position":
            None,
        },
        # Annotation without assignment
        {
            "node":
            cst.SimpleStatementLine((cst.AnnAssign(
                target=cst.Name("foo"),
                annotation=cst.Annotation(
                    annotation=cst.Name("str"),
                    whitespace_before_indicator=cst.SimpleWhitespace(""),
                ),
                value=None,
            ), )),
            "code":
            "foo: str\n",
            "parser":
            parse_statement,
            "expected_position":
            None,
        },
        # Complex annotation
        {
            "node":
            cst.SimpleStatementLine((cst.AnnAssign(
                target=cst.Name("foo"),
                annotation=cst.Annotation(
                    annotation=cst.Subscript(
                        cst.Name("Optional"),
                        (cst.SubscriptElement(cst.Index(cst.Name("str"))), ),
                    ),
                    whitespace_before_indicator=cst.SimpleWhitespace(""),
                ),
                equal=cst.AssignEqual(),
                value=cst.Integer("5"),
            ), )),
            "code":
            "foo: Optional[str] = 5\n",
            "parser":
            parse_statement,
            "expected_position":
            None,
        },
        # Whitespace test
        {
            "node":
            cst.AnnAssign(
                target=cst.Name("foo"),
                annotation=cst.Annotation(
                    annotation=cst.Subscript(
                        cst.Name("Optional"),
                        (cst.SubscriptElement(cst.Index(cst.Name("str"))), ),
                    ),
                    whitespace_before_indicator=cst.SimpleWhitespace(" "),
                    whitespace_after_indicator=cst.SimpleWhitespace("  "),
                ),
                equal=cst.AssignEqual(
                    whitespace_before=cst.SimpleWhitespace("  "),
                    whitespace_after=cst.SimpleWhitespace("  "),
                ),
                value=cst.Integer("5"),
            ),
            "code":
            "foo :  Optional[str]  =  5",
            "parser":
            None,
            "expected_position":
            CodeRange((1, 0), (1, 26)),
        },
        {
            "node":
            cst.SimpleStatementLine((cst.AnnAssign(
                target=cst.Name("foo"),
                annotation=cst.Annotation(
                    annotation=cst.Subscript(
                        cst.Name("Optional"),
                        (cst.SubscriptElement(cst.Index(cst.Name("str"))), ),
                    ),
                    whitespace_before_indicator=cst.SimpleWhitespace(" "),
                    whitespace_after_indicator=cst.SimpleWhitespace("  "),
                ),
                equal=cst.AssignEqual(
                    whitespace_before=cst.SimpleWhitespace("  "),
                    whitespace_after=cst.SimpleWhitespace("  "),
                ),
                value=cst.Integer("5"),
            ), )),
            "code":
            "foo :  Optional[str]  =  5\n",
            "parser":
            parse_statement,
            "expected_position":
            None,
        },
    ))
    def test_valid(self, **kwargs: Any) -> None:
        self.validate_node(**kwargs)

    @data_provider(({
        "get_node": (lambda: cst.AnnAssign(
            target=cst.Name("foo"),
            annotation=cst.Annotation(cst.Name("str")),
            equal=cst.AssignEqual(),
            value=None,
        )),
        "expected_re":
        "Must have a value when specifying an AssignEqual.",
    }, ))
    def test_invalid(self, **kwargs: Any) -> None:
        self.assert_invalid(**kwargs)

    @data_provider((
        {
            "get_node": (
                lambda: cst.AnnAssign(
                    # pyre-ignore: Incompatible parameter type [6]
                    target=cst.BinaryOperation(
                        left=cst.Name("x"),
                        operator=cst.Add(),
                        right=cst.Integer("1"),
                    ),
                    annotation=cst.Annotation(cst.Name("int")),
                    equal=cst.AssignEqual(),
                    value=cst.Name("y"),
                )),
            "expected_re":
            ("Expected an instance of .*BaseAssignTargetExpression.*"),
        }, ))
    def test_invalid_types(self, **kwargs: Any) -> None:
        self.assert_invalid_types(**kwargs)
Esempio n. 10
0
class AssignTest(CSTNodeTest):
    @data_provider((
        # Simple assignment creation case.
        {
            "node":
            cst.Assign((cst.AssignTarget(cst.Name("foo")), ),
                       cst.Integer("5")),
            "code":
            "foo = 5",
            "parser":
            None,
            "expected_position":
            CodeRange((1, 0), (1, 7)),
        },
        # Multiple targets creation
        {
            "node":
            cst.Assign(
                (
                    cst.AssignTarget(cst.Name("foo")),
                    cst.AssignTarget(cst.Name("bar")),
                ),
                cst.Integer("5"),
            ),
            "code":
            "foo = bar = 5",
            "parser":
            None,
            "expected_position":
            CodeRange((1, 0), (1, 13)),
        },
        # Whitespace test for creating nodes
        {
            "node":
            cst.Assign(
                (cst.AssignTarget(
                    cst.Name("foo"),
                    whitespace_before_equal=cst.SimpleWhitespace(""),
                    whitespace_after_equal=cst.SimpleWhitespace(""),
                ), ),
                cst.Integer("5"),
            ),
            "code":
            "foo=5",
            "parser":
            None,
            "expected_position":
            CodeRange((1, 0), (1, 5)),
        },
        # Simple assignment parser case.
        {
            "node":
            cst.SimpleStatementLine((cst.Assign(
                (cst.AssignTarget(cst.Name("foo")), ), cst.Integer("5")), )),
            "code":
            "foo = 5\n",
            "parser":
            parse_statement,
            "expected_position":
            None,
        },
        # Multiple targets parser
        {
            "node":
            cst.SimpleStatementLine((cst.Assign(
                (
                    cst.AssignTarget(cst.Name("foo")),
                    cst.AssignTarget(cst.Name("bar")),
                ),
                cst.Integer("5"),
            ), )),
            "code":
            "foo = bar = 5\n",
            "parser":
            parse_statement,
            "expected_position":
            None,
        },
        # Whitespace test parser
        {
            "node":
            cst.SimpleStatementLine((cst.Assign(
                (cst.AssignTarget(
                    cst.Name("foo"),
                    whitespace_before_equal=cst.SimpleWhitespace(""),
                    whitespace_after_equal=cst.SimpleWhitespace(""),
                ), ),
                cst.Integer("5"),
            ), )),
            "code":
            "foo=5\n",
            "parser":
            parse_statement,
            "expected_position":
            None,
        },
    ))
    def test_valid(self, **kwargs: Any) -> None:
        self.validate_node(**kwargs)

    @data_provider(({
        "get_node": (lambda: cst.Assign(targets=(), value=cst.Integer("5"))),
        "expected_re":
        "at least one AssignTarget",
    }, ))
    def test_invalid(self, **kwargs: Any) -> None:
        self.assert_invalid(**kwargs)

    @data_provider((
        {
            "get_node": (
                lambda: cst.Assign(
                    # pyre-ignore: Incompatible parameter type [6]
                    targets=[
                        cst.BinaryOperation(
                            left=cst.Name("x"),
                            operator=cst.Add(),
                            right=cst.Integer("1"),
                        ),
                    ],
                    value=cst.Name("y"),
                )),
            "expected_re":
            "Expected an instance of .*statement.AssignTarget.*",
        }, ))
    def test_invalid_types(self, **kwargs: Any) -> None:
        self.assert_invalid_types(**kwargs)
Esempio n. 11
0
 def add(left, right):
     return cst.BinaryOperation(left, cst.Add(), right)