Skip to content

Commit

Permalink
Merge pull request #16
Browse files Browse the repository at this point in the history
Fix necessary parentheses in multi-line unpacking
  • Loading branch information
robsdedude authored Sep 22, 2022
2 parents 4626280 + 913e012 commit b1d8c51
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 38 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,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:
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
Changelog
=========

## 0.1.1
***
**🔧 Fixes**
* Fix complaining about necessary parentheses in multi-line unpacking
assignments
([#16](https://github.com/robsdedude/flake8-picky-parentheses/pull/16)).

## 0.1.0
***
**🎉 Initial release**
72 changes: 35 additions & 37 deletions flake8_picky_parentheses/_redundant_parentheses.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,7 @@ 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:
msg = "PAR001: Too many parentheses"
Expand All @@ -93,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:
Expand All @@ -103,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
Expand All @@ -117,53 +115,53 @@ 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
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))
):
if self._node_in_parens(elt, coords):
matching_parens = coords
break
self.problems.append((
node.lineno, node.col_offset,
"PAR002: Dont use parentheses for "
"unpacking"
))
break
if breaker:
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

if isinstance(node, ast.Tuple):
self.problems.append((
node.lineno, node.col_offset,
"PAR002: Dont use parentheses for "
"unpacking"
))
# no need to treat them again later
self.exceptions.append(matching_parens)
break

elif isinstance(node, ast.Tuple):
for coords in self.parens_coords:
if self.checked_parentheses(coords):
continue
if self._check_parens_is_tuple(node, coords):
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
Expand All @@ -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
Expand Down
16 changes: 16 additions & 0 deletions tests/test_redundant_parentheses.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,22 @@ def test_ugly_multiline_unpacking(plugin):
assert len(plugin(s)) == 1


# GOOD (unpacking with line break)
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:
Expand Down

0 comments on commit b1d8c51

Please # to comment.