From 40f7429922194a9174728d55d9ce5f38149ae50b Mon Sep 17 00:00:00 2001 From: Robsdedude Date: Wed, 21 Sep 2022 13:52:59 +0200 Subject: [PATCH 1/7] Let's eat our own dog food ;) Enabling picky parentheses to run on itself. --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e371b18..8b9b6b5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,7 +27,7 @@ repos: - flake8-bugbear - flake8-builtins - flake8-docstrings - # - flake8-picky-parentheses + - flake8-picky-parentheses - flake8-quotes - pep8-naming - repo: local From 212b833c7f96e1754285f0d8dd972f96a0462c62 Mon Sep 17 00:00:00 2001 From: IvanPrychantovskyi <109072205+IvanPrychantovskyi@users.noreply.github.com> Date: Wed, 21 Sep 2022 14:57:33 +0100 Subject: [PATCH 2/7] Fix unpacking bug --- CHANGELOG.md | 4 ++++ flake8_picky_parentheses/_redundant_parentheses.py | 8 ++++++++ tests/test_redundant_parentheses.py | 8 ++++++++ 3 files changed, 20 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f0d36f..aabe9ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ Changelog ========= +## 0.1.1 +*** +*** Fix of unpacking necessary parentheses + ## 0.1.0 *** **🎉 Initial release** diff --git a/flake8_picky_parentheses/_redundant_parentheses.py b/flake8_picky_parentheses/_redundant_parentheses.py index 033fa18..96ed66f 100644 --- a/flake8_picky_parentheses/_redundant_parentheses.py +++ b/flake8_picky_parentheses/_redundant_parentheses.py @@ -86,6 +86,7 @@ def checked_parentheses(self, coords) -> bool: return False def check(self) -> None: + breaker_ = None msg = "PAR001: Too many parentheses" # exceptions made for parentheses that are not strictly necessary # but help readability @@ -146,6 +147,13 @@ def check(self) -> None: for token in range(len(self.file_tokens_nn)) ): break + for coords in self.all_parens_coords: + if (tuple_coords == coords.open_ + and coords.open_[0] != coords.close[0] + and coords not in self.parens_coords): + breaker_ = 1 + if breaker_: + break self.problems.append(( node.lineno, node.col_offset, "PAR002: Dont use parentheses for " diff --git a/tests/test_redundant_parentheses.py b/tests/test_redundant_parentheses.py index d7d2fcb..9779ec5 100644 --- a/tests/test_redundant_parentheses.py +++ b/tests/test_redundant_parentheses.py @@ -157,6 +157,14 @@ def test_ugly_multiline_unpacking(plugin): assert len(plugin(s)) == 1 +# GOOD (unpacking with line break) +def test_multiline_unpacking(plugin): + s = """( +a, b +) = 1, 2""" + assert not plugin(s) + + # GOOD (parentheses for tuple literal are optional) def test_tuple_literal_unpacking_in_if(plugin): s = """if foo: From ff40a85911a64e6095e5aa451c3bf7f2c802996c Mon Sep 17 00:00:00 2001 From: Robsdedude Date: Wed, 21 Sep 2022 16:03:55 +0200 Subject: [PATCH 3/7] changelog clean-up --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aabe9ce..5009b44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,10 @@ Changelog ## 0.1.1 *** -*** Fix of unpacking necessary parentheses +**🔧 Fixes** +* Fix complaining about necessary parentheses in multi-line unpacking + assignments + ([#16](https://github.com/robsdedude/flake8-picky-parentheses/pull/16)). ## 0.1.0 *** From d477e6c62d342d4a4c73ad3c132977b13f64b61c Mon Sep 17 00:00:00 2001 From: Robsdedude Date: Wed, 21 Sep 2022 17:36:38 +0200 Subject: [PATCH 4/7] Simplify fix and also fix Python 3.7 --- .../_redundant_parentheses.py | 60 ++++++++----------- tests/test_redundant_parentheses.py | 10 +++- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/flake8_picky_parentheses/_redundant_parentheses.py b/flake8_picky_parentheses/_redundant_parentheses.py index 96ed66f..9f161ea 100644 --- a/flake8_picky_parentheses/_redundant_parentheses.py +++ b/flake8_picky_parentheses/_redundant_parentheses.py @@ -81,12 +81,9 @@ def _check_parens_is_tuple(node, parens_coords): ) def checked_parentheses(self, coords) -> bool: - if coords in self.exceptions or coords[0] in self.problems: - return True - return False + return coords in self.exceptions or coords[0] in self.problems def check(self) -> None: - breaker_ = None msg = "PAR001: Too many parentheses" # exceptions made for parentheses that are not strictly necessary # but help readability @@ -127,39 +124,34 @@ def check(self) -> None: for target in node.targets: if not isinstance(target, ast.Tuple): continue - for elts in target.elts: - tuple_coords = (target.lineno, target.col_offset) - elts_coords = (elts.lineno, elts.col_offset) - if tuple_coords > elts_coords: + if not target.elts: + continue + elt = target.elts[0] + elt_coords = (elt.lineno, elt.col_offset) + matching_parens = None + for coords in self.parens_coords: + if self.checked_parentheses(coords): continue - for coords in self.parens_coords: - if self.checked_parentheses(coords): - continue - if (coords[0][1] <= tuple_coords[1] - and coords[0][0] == tuple_coords[0]): - self.exceptions.append(coords) - breaker = 1 - break - if not any( - self.file_tokens_nn[token].start == elts_coords - and self.file_tokens_nn[token - 1].string - == "(" - for token in range(len(self.file_tokens_nn)) - ): - break - for coords in self.all_parens_coords: - if (tuple_coords == coords.open_ - and coords.open_[0] != coords.close[0] - and coords not in self.parens_coords): - breaker_ = 1 - if breaker_: + if coords.open_ <= elt_coords <= coords.close: + # no need to treat them again later + self.exceptions.append(coords) + matching_parens = coords + breaker = 1 break - self.problems.append(( - node.lineno, node.col_offset, - "PAR002: Dont use parentheses for " - "unpacking" - )) + if not matching_parens: + continue + if not any( + self.file_tokens_nn[token].start == elt_coords + and self.file_tokens_nn[token - 1].string + == "(" + for token in range(len(self.file_tokens_nn)) + ): break + self.problems.append(( + node.lineno, node.col_offset, + "PAR002: Dont use parentheses for " + "unpacking" + )) if breaker: break diff --git a/tests/test_redundant_parentheses.py b/tests/test_redundant_parentheses.py index 9779ec5..ca9f26f 100644 --- a/tests/test_redundant_parentheses.py +++ b/tests/test_redundant_parentheses.py @@ -158,13 +158,21 @@ def test_ugly_multiline_unpacking(plugin): # GOOD (unpacking with line break) -def test_multiline_unpacking(plugin): +def test_multiline_unpacking_implicit_tuple_literal(plugin): s = """( a, b ) = 1, 2""" assert not plugin(s) +# GOOD (unpacking with line break) +def test_multiline_unpacking_explicit_tuple_literal(plugin): + s = """( +a, b +) = (1, 2)""" + assert not plugin(s) + + # GOOD (parentheses for tuple literal are optional) def test_tuple_literal_unpacking_in_if(plugin): s = """if foo: From 492beea2238c25a66cbbcd06abfa440a7af1e456 Mon Sep 17 00:00:00 2001 From: Robsdedude Date: Wed, 21 Sep 2022 17:45:27 +0200 Subject: [PATCH 5/7] GH actions: rename job 'build' -> 'tests' --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6167679..190d11c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -13,7 +13,7 @@ jobs: - uses: actions/setup-python@v4 - run: pip install -r requirements.txt - uses: pre-commit/action@v3.0.0 - build: + tests: runs-on: ubuntu-latest strategy: matrix: From 334dc6d620f9f9df808dfb4f19b4d1b63467c6d4 Mon Sep 17 00:00:00 2001 From: Robsdedude Date: Wed, 21 Sep 2022 17:46:16 +0200 Subject: [PATCH 6/7] Tiny refactor --- .../_redundant_parentheses.py | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/flake8_picky_parentheses/_redundant_parentheses.py b/flake8_picky_parentheses/_redundant_parentheses.py index 9f161ea..00fdd35 100644 --- a/flake8_picky_parentheses/_redundant_parentheses.py +++ b/flake8_picky_parentheses/_redundant_parentheses.py @@ -91,7 +91,7 @@ def check(self) -> None: ast.BinOp, ast.BoolOp, ast.UnaryOp, ast.Compare, ast.Await ) for node in ast.walk(self.tree): - breaker = None + breaker = False if isinstance(node, ast.Slice): for child in ast.iter_child_nodes(node): for coords in self.parens_coords: @@ -101,11 +101,11 @@ def check(self) -> None: == (child.lineno, child.col_offset) and isinstance(child, special_ops_pair_exceptions)): - breaker = 1 + breaker = True self.exceptions.append(coords) if breaker: break - if isinstance(node, special_ops_pair_exceptions): + elif isinstance(node, special_ops_pair_exceptions): for child in ast.iter_child_nodes(node): if not isinstance(child, special_ops_pair_exceptions): continue @@ -115,12 +115,12 @@ def check(self) -> None: continue if self._node_in_parens(child, coords): self.exceptions.append(coords) - breaker = 1 + breaker = True break if breaker: break - if isinstance(node, ast.Assign): + elif isinstance(node, ast.Assign): for target in node.targets: if not isinstance(target, ast.Tuple): continue @@ -132,11 +132,8 @@ def check(self) -> None: for coords in self.parens_coords: if self.checked_parentheses(coords): continue - if coords.open_ <= elt_coords <= coords.close: - # no need to treat them again later - self.exceptions.append(coords) + if self._node_in_parens(elt, coords): matching_parens = coords - breaker = 1 break if not matching_parens: continue @@ -152,10 +149,11 @@ def check(self) -> None: "PAR002: Dont use parentheses for " "unpacking" )) - if breaker: - break + # no need to treat them again later + self.exceptions.append(matching_parens) + break - if isinstance(node, ast.Tuple): + elif isinstance(node, ast.Tuple): for coords in self.parens_coords: if self.checked_parentheses(coords): continue @@ -163,7 +161,7 @@ def check(self) -> None: self.exceptions.append(coords) break - if isinstance(node, ast.comprehension): + elif isinstance(node, ast.comprehension): for coords in self.parens_coords: if self.checked_parentheses(coords): continue @@ -172,7 +170,7 @@ def check(self) -> None: break if coords.open_[0] != coords.close[0]: self.exceptions.append(coords) - breaker = 1 + breaker = True break if breaker: break From 913e012ce5406cd152b5eb8519f7dccd6b62bdd6 Mon Sep 17 00:00:00 2001 From: Robsdedude Date: Thu, 22 Sep 2022 10:50:45 +0200 Subject: [PATCH 7/7] Revert "Let's eat our own dog food ;)" This reverts commit 40f7429922194a9174728d55d9ce5f38149ae50b. --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8b9b6b5..e371b18 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,7 +27,7 @@ repos: - flake8-bugbear - flake8-builtins - flake8-docstrings - - flake8-picky-parentheses + # - flake8-picky-parentheses - flake8-quotes - pep8-naming - repo: local