From c2a6c264338e8534017320dff1314faf43e71764 Mon Sep 17 00:00:00 2001 From: Richard Si <63936253+ichard26@users.noreply.github.com> Date: Sun, 2 May 2021 23:17:11 -0400 Subject: [PATCH] Detect `'@' dotted_name '(' ')' NEWLINE` as a simple decorator Previously the RELAXED_DECORATOR detection would be falsely True on that example. The problem was that an argument-less parentheses pair didn't pass the `is_simple_decorator_trailer` check even it should. OTOH a parentheses pair containing an argument or more passed as expected. --- CHANGES.md | 3 +++ src/black/__init__.py | 9 +++++++++ tests/data/decorators.py | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 321f8c083b2..899b102d95c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,9 @@ - Set `--pyi` mode if `--stdin-filename` ends in `.pyi` (#2169) +- Stop detecting target version as Python 3.9+ with pre-PEP-614 decorators that are + being called but with no arguments (#2182) + ### 21.4b2 #### _Black_ diff --git a/src/black/__init__.py b/src/black/__init__.py index 49d088b531d..e4668eae230 100644 --- a/src/black/__init__.py +++ b/src/black/__init__.py @@ -5761,6 +5761,13 @@ def is_simple_decorator_trailer(node: LN, last: bool = False) -> bool: and node.children[0].type == token.DOT and node.children[1].type == token.NAME ) + # last trailer can be an argument-less parentheses pair + or ( + last + and len(node.children) == 2 + and node.children[0].type == token.LPAR + and node.children[1].type == token.RPAR + ) # last trailer can be arguments or ( last @@ -5781,6 +5788,7 @@ def is_simple_decorator_expression(node: LN) -> bool: The old grammar was: decorator: @ dotted_name [arguments] NEWLINE The new grammar is : decorator: @ namedexpr_test NEWLINE """ + print(f"{node!r}") if node.type == token.NAME: return True if node.type == syms.power: @@ -6003,6 +6011,7 @@ def get_features_used(node: Node) -> Set[Feature]: features.add(Feature.ASSIGNMENT_EXPRESSIONS) elif n.type == syms.decorator: + print("uh") if len(n.children) > 1 and not is_simple_decorator_expression( n.children[1] ): diff --git a/tests/data/decorators.py b/tests/data/decorators.py index acfad51fcb8..a0f38ca7b9d 100644 --- a/tests/data/decorators.py +++ b/tests/data/decorators.py @@ -13,6 +13,12 @@ def f(): ## +@decorator() +def f(): + ... + +## + @decorator(arg) def f(): ...