From 80500748a7b4246e2381ddce869a09a215a591ae Mon Sep 17 00:00:00 2001 From: Zsolt Dollenstein Date: Mon, 17 Sep 2018 12:03:21 +0100 Subject: [PATCH] fix unstable formatting when unpacking big tuples (#514) * fix unstable formatting when unpacking big tuples * add changelog entry --- README.md | 2 ++ black.py | 12 ++++------ tests/data/expression.diff | 47 +++++++++++++++++++++++--------------- tests/data/expression.py | 10 ++++++++ 4 files changed, 44 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 6aad8bc..6d350d0 100644 --- a/README.md +++ b/README.md @@ -874,6 +874,8 @@ More details can be found in [CONTRIBUTING](CONTRIBUTING.md). * *Black* no longer breaks ``async for`` statements up to separate lines (#372) +* fixed unstable formatting when unpacking big tuples (#267) + ### 18.6b4 diff --git a/black.py b/black.py index 6f7496e..8d53194 100644 --- a/black.py +++ b/black.py @@ -2976,7 +2976,6 @@ def generate_trailers_to_omit(line: Line, line_length: int) -> Iterator[Set[Leaf length = 4 * line.depth opening_bracket = None closing_bracket = None - optional_brackets: Set[LeafID] = set() inner_brackets: Set[LeafID] = set() for index, leaf, leaf_length in enumerate_with_length(line, reversed=True): length += leaf_length @@ -2987,17 +2986,12 @@ def generate_trailers_to_omit(line: Line, line_length: int) -> Iterator[Set[Leaf if leaf.type == STANDALONE_COMMENT or has_inline_comment: break - optional_brackets.discard(id(leaf)) if opening_bracket: if leaf is opening_bracket: opening_bracket = None elif leaf.type in CLOSING_BRACKETS: inner_brackets.add(id(leaf)) elif leaf.type in CLOSING_BRACKETS: - if not leaf.value: - optional_brackets.add(id(opening_bracket)) - continue - if index > 0 and line.leaves[index - 1].type in OPENING_BRACKETS: # Empty brackets would fail a split so treat them as "inner" # brackets (e.g. only add them to the `omit` set if another @@ -3005,13 +2999,15 @@ def generate_trailers_to_omit(line: Line, line_length: int) -> Iterator[Set[Leaf inner_brackets.add(id(leaf)) continue - opening_bracket = leaf.opening_bracket if closing_bracket: omit.add(id(closing_bracket)) omit.update(inner_brackets) inner_brackets.clear() yield omit - closing_bracket = leaf + + if leaf.value: + opening_bracket = leaf.opening_bracket + closing_bracket = leaf def get_future_imports(node: Node) -> Set[str]: diff --git a/tests/data/expression.diff b/tests/data/expression.diff index 8b73f32..b26d931 100644 --- a/tests/data/expression.diff +++ b/tests/data/expression.diff @@ -147,7 +147,7 @@ slice[0:1:2] slice[:] slice[:-1] -@@ -133,109 +156,161 @@ +@@ -133,111 +156,169 @@ numpy[-(c + 1) :, d] numpy[:, l[-2]] numpy[:, ::-1] @@ -234,6 +234,33 @@ -for i in (call()): ... -for j in (1 + (2 + 3)): ... -while(this and that): ... +-for addr_family, addr_type, addr_proto, addr_canonname, addr_sockaddr in socket.getaddrinfo('google.com', 'http'): ++print(*lambda x: x) ++assert not Test, "Short message" ++assert this is ComplexTest and not requirements.fit_in_a_single_line( ++ force=False ++), "Short message" ++assert parens is TooMany ++for (x,) in (1,), (2,), (3,): ++ ... ++for y in (): ++ ... ++for z in (i for i in (1, 2, 3)): ++ ... ++for i in call(): ++ ... ++for j in 1 + (2 + 3): ++ ... ++while this and that: ++ ... ++for ( ++ addr_family, ++ addr_type, ++ addr_proto, ++ addr_canonname, ++ addr_sockaddr, ++) in socket.getaddrinfo("google.com", "http"): + pass -a = aaaa.bbbb.cccc.dddd.eeee.ffff.gggg.hhhh.iiii.jjjj.kkkk.llll.mmmm.nnnn.oooo.pppp in qqqq.rrrr.ssss.tttt.uuuu.vvvv.xxxx.yyyy.zzzz -a = aaaa.bbbb.cccc.dddd.eeee.ffff.gggg.hhhh.iiii.jjjj.kkkk.llll.mmmm.nnnn.oooo.pppp not in qqqq.rrrr.ssss.tttt.uuuu.vvvv.xxxx.yyyy.zzzz -a = aaaa.bbbb.cccc.dddd.eeee.ffff.gggg.hhhh.iiii.jjjj.kkkk.llll.mmmm.nnnn.oooo.pppp is qqqq.rrrr.ssss.tttt.uuuu.vvvv.xxxx.yyyy.zzzz @@ -284,24 +311,6 @@ - return True -if ( - ~ aaaaaaaaaaaaaaaa.a + aaaaaaaaaaaaaaaa.b - aaaaaaaaaaaaaaaa.c * aaaaaaaaaaaaaaaa.d @ aaaaaaaaaaaaaaaa.e | aaaaaaaaaaaaaaaa.f & aaaaaaaaaaaaaaaa.g % aaaaaaaaaaaaaaaa.h ^ aaaaaaaaaaaaaaaa.i << aaaaaaaaaaaaaaaa.k >> aaaaaaaaaaaaaaaa.l ** aaaaaaaaaaaaaaaa.m // aaaaaaaaaaaaaaaa.n -+print(*lambda x: x) -+assert not Test, "Short message" -+assert this is ComplexTest and not requirements.fit_in_a_single_line( -+ force=False -+), "Short message" -+assert parens is TooMany -+for (x,) in (1,), (2,), (3,): -+ ... -+for y in (): -+ ... -+for z in (i for i in (1, 2, 3)): -+ ... -+for i in call(): -+ ... -+for j in 1 + (2 + 3): -+ ... -+while this and that: -+ ... +a = ( + aaaa.bbbb.cccc.dddd.eeee.ffff.gggg.hhhh.iiii.jjjj.kkkk.llll.mmmm.nnnn.oooo.pppp + in qqqq.rrrr.ssss.tttt.uuuu.vvvv.xxxx.yyyy.zzzz diff --git a/tests/data/expression.py b/tests/data/expression.py index b1fa66b..71cf1d9 100644 --- a/tests/data/expression.py +++ b/tests/data/expression.py @@ -184,6 +184,8 @@ for z in (i for i in (1, 2, 3)): ... for i in (call()): ... for j in (1 + (2 + 3)): ... while(this and that): ... +for addr_family, addr_type, addr_proto, addr_canonname, addr_sockaddr in socket.getaddrinfo('google.com', 'http'): + pass a = aaaa.bbbb.cccc.dddd.eeee.ffff.gggg.hhhh.iiii.jjjj.kkkk.llll.mmmm.nnnn.oooo.pppp in qqqq.rrrr.ssss.tttt.uuuu.vvvv.xxxx.yyyy.zzzz a = aaaa.bbbb.cccc.dddd.eeee.ffff.gggg.hhhh.iiii.jjjj.kkkk.llll.mmmm.nnnn.oooo.pppp not in qqqq.rrrr.ssss.tttt.uuuu.vvvv.xxxx.yyyy.zzzz a = aaaa.bbbb.cccc.dddd.eeee.ffff.gggg.hhhh.iiii.jjjj.kkkk.llll.mmmm.nnnn.oooo.pppp is qqqq.rrrr.ssss.tttt.uuuu.vvvv.xxxx.yyyy.zzzz @@ -483,6 +485,14 @@ for j in 1 + (2 + 3): ... while this and that: ... +for ( + addr_family, + addr_type, + addr_proto, + addr_canonname, + addr_sockaddr, +) in socket.getaddrinfo("google.com", "http"): + pass a = ( aaaa.bbbb.cccc.dddd.eeee.ffff.gggg.hhhh.iiii.jjjj.kkkk.llll.mmmm.nnnn.oooo.pppp in qqqq.rrrr.ssss.tttt.uuuu.vvvv.xxxx.yyyy.zzzz -- 2.39.5