Skip to content

Commit

Permalink
Fix a crash in preview style with assert + parenthesized string. (#3415)
Browse files Browse the repository at this point in the history
The bug is in the `get_leaves_inside_matching_brackets` on the third line below:

```python
assert xxxxxxxxx.xxxxxxxxx.xxxxxxxxx(
    xxxxxxxxx
).xxxxxxxxxxxxxxxxxx(), (
    "xxx {xxxxxxxxx} xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
)
```

Including the invisible paren, third line is `).xxxxxxxxxxxxxxxxxx()), (`, that it has a matched pair then an unmatched closing paren afterwards. This PR ensures the returned leaves are actually matched.

Fixes #3414.
  • Loading branch information
yilei committed Dec 10, 2022
1 parent 1f7f6de commit 96e62c5
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 14 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Expand Up @@ -14,6 +14,8 @@

<!-- Changes that affect Black's preview style -->

- Fix a crash in preview style with assert + parenthesized string (#3415)

### Configuration

<!-- Changes to how Black can be configured -->
Expand Down
25 changes: 11 additions & 14 deletions src/black/brackets.py
Expand Up @@ -349,26 +349,23 @@ def get_leaves_inside_matching_brackets(leaves: Sequence[Leaf]) -> Set[LeafID]:
Matching brackets are included.
"""
try:
# Only track brackets from the first opening bracket to the last closing
# bracket.
# Start with the first opening bracket and ignore closing brackets before.
start_index = next(
i for i, l in enumerate(leaves) if l.type in OPENING_BRACKETS
)
end_index = next(
len(leaves) - i
for i, l in enumerate(reversed(leaves))
if l.type in CLOSING_BRACKETS
)
except StopIteration:
return set()
bracket_stack = []
ids = set()
depth = 0
for i in range(end_index, start_index - 1, -1):
for i in range(start_index, len(leaves)):
leaf = leaves[i]
if leaf.type in CLOSING_BRACKETS:
depth += 1
if depth > 0:
ids.add(id(leaf))
if leaf.type in OPENING_BRACKETS:
depth -= 1
bracket_stack.append((BRACKET[leaf.type], i))
if leaf.type in CLOSING_BRACKETS:
if bracket_stack and leaf.type == bracket_stack[-1][0]:
_, start = bracket_stack.pop()
for j in range(start, i + 1):
ids.add(id(leaves[j]))
else:
break
return ids
14 changes: 14 additions & 0 deletions tests/data/preview/trailing_commas_in_leading_parts.py
Expand Up @@ -25,6 +25,13 @@ def refresh_token(self, device_family, refresh_token, api_key):
== long_module.long_class.long_func()["some_key"].another_func(arg1)
)

# Regression test for https://github.com/psf/black/issues/3414.
assert xxxxxxxxx.xxxxxxxxx.xxxxxxxxx(
xxxxxxxxx
).xxxxxxxxxxxxxxxxxx(), (
"xxx {xxxxxxxxx} xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
)


# output

Expand Down Expand Up @@ -72,3 +79,10 @@ def refresh_token(self, device_family, refresh_token, api_key):
long_module.long_class.long_func().another_func()
== long_module.long_class.long_func()["some_key"].another_func(arg1)
)

# Regression test for https://github.com/psf/black/issues/3414.
assert xxxxxxxxx.xxxxxxxxx.xxxxxxxxx(
xxxxxxxxx
).xxxxxxxxxxxxxxxxxx(), (
"xxx {xxxxxxxxx} xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
)

0 comments on commit 96e62c5

Please sign in to comment.