fix bracket match bug (#470)
* fix bracket match bug * add missing test file
This commit is contained in:
parent
8b340e2102
commit
b53cb94743
25
black.py
25
black.py
@ -877,8 +877,8 @@ class BracketTracker:
|
|||||||
bracket_match: Dict[Tuple[Depth, NodeType], Leaf] = Factory(dict)
|
bracket_match: Dict[Tuple[Depth, NodeType], Leaf] = Factory(dict)
|
||||||
delimiters: Dict[LeafID, Priority] = Factory(dict)
|
delimiters: Dict[LeafID, Priority] = Factory(dict)
|
||||||
previous: Optional[Leaf] = None
|
previous: Optional[Leaf] = None
|
||||||
_for_loop_variable: int = 0
|
_for_loop_depths: List[int] = Factory(list)
|
||||||
_lambda_arguments: int = 0
|
_lambda_argument_depths: List[int] = Factory(list)
|
||||||
|
|
||||||
def mark(self, leaf: Leaf) -> None:
|
def mark(self, leaf: Leaf) -> None:
|
||||||
"""Mark `leaf` with bracket-related metadata. Keep track of delimiters.
|
"""Mark `leaf` with bracket-related metadata. Keep track of delimiters.
|
||||||
@ -951,16 +951,21 @@ def maybe_increment_for_loop_variable(self, leaf: Leaf) -> bool:
|
|||||||
"""
|
"""
|
||||||
if leaf.type == token.NAME and leaf.value == "for":
|
if leaf.type == token.NAME and leaf.value == "for":
|
||||||
self.depth += 1
|
self.depth += 1
|
||||||
self._for_loop_variable += 1
|
self._for_loop_depths.append(self.depth)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def maybe_decrement_after_for_loop_variable(self, leaf: Leaf) -> bool:
|
def maybe_decrement_after_for_loop_variable(self, leaf: Leaf) -> bool:
|
||||||
"""See `maybe_increment_for_loop_variable` above for explanation."""
|
"""See `maybe_increment_for_loop_variable` above for explanation."""
|
||||||
if self._for_loop_variable and leaf.type == token.NAME and leaf.value == "in":
|
if (
|
||||||
|
self._for_loop_depths
|
||||||
|
and self._for_loop_depths[-1] == self.depth
|
||||||
|
and leaf.type == token.NAME
|
||||||
|
and leaf.value == "in"
|
||||||
|
):
|
||||||
self.depth -= 1
|
self.depth -= 1
|
||||||
self._for_loop_variable -= 1
|
self._for_loop_depths.pop()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
@ -973,16 +978,20 @@ def maybe_increment_lambda_arguments(self, leaf: Leaf) -> bool:
|
|||||||
"""
|
"""
|
||||||
if leaf.type == token.NAME and leaf.value == "lambda":
|
if leaf.type == token.NAME and leaf.value == "lambda":
|
||||||
self.depth += 1
|
self.depth += 1
|
||||||
self._lambda_arguments += 1
|
self._lambda_argument_depths.append(self.depth)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def maybe_decrement_after_lambda_arguments(self, leaf: Leaf) -> bool:
|
def maybe_decrement_after_lambda_arguments(self, leaf: Leaf) -> bool:
|
||||||
"""See `maybe_increment_lambda_arguments` above for explanation."""
|
"""See `maybe_increment_lambda_arguments` above for explanation."""
|
||||||
if self._lambda_arguments and leaf.type == token.COLON:
|
if (
|
||||||
|
self._lambda_argument_depths
|
||||||
|
and self._lambda_argument_depths[-1] == self.depth
|
||||||
|
and leaf.type == token.COLON
|
||||||
|
):
|
||||||
self.depth -= 1
|
self.depth -= 1
|
||||||
self._lambda_arguments -= 1
|
self._lambda_argument_depths.pop()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
15
tests/data/bracketmatch.py
Normal file
15
tests/data/bracketmatch.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
for ((x in {}) or {})['a'] in x:
|
||||||
|
pass
|
||||||
|
pem_spam = lambda l, spam = {
|
||||||
|
"x": 3
|
||||||
|
}: not spam.get(l.strip())
|
||||||
|
lambda x=lambda y={1: 3}: y['x':lambda y: {1: 2}]: x
|
||||||
|
|
||||||
|
|
||||||
|
# output
|
||||||
|
|
||||||
|
|
||||||
|
for ((x in {}) or {})["a"] in x:
|
||||||
|
pass
|
||||||
|
pem_spam = lambda l, spam={"x": 3}: not spam.get(l.strip())
|
||||||
|
lambda x=lambda y={1: 3}: y["x" : lambda y: {1: 2}]: x
|
@ -453,6 +453,14 @@ def test_new_line_between_class_and_code(self) -> None:
|
|||||||
black.assert_equivalent(source, actual)
|
black.assert_equivalent(source, actual)
|
||||||
black.assert_stable(source, actual, line_length=ll)
|
black.assert_stable(source, actual, line_length=ll)
|
||||||
|
|
||||||
|
@patch("black.dump_to_file", dump_to_stderr)
|
||||||
|
def test_bracket_match(self) -> None:
|
||||||
|
source, expected = read_data("bracketmatch")
|
||||||
|
actual = fs(source)
|
||||||
|
self.assertFormatEqual(expected, actual)
|
||||||
|
black.assert_equivalent(source, actual)
|
||||||
|
black.assert_stable(source, actual, line_length=ll)
|
||||||
|
|
||||||
def test_report_verbose(self) -> None:
|
def test_report_verbose(self) -> None:
|
||||||
report = black.Report(verbose=True)
|
report = black.Report(verbose=True)
|
||||||
out_lines = []
|
out_lines = []
|
||||||
|
Loading…
Reference in New Issue
Block a user