fix: Remove parenthesis around sole list items (#4312)
This commit is contained in:
parent
17efac45f9
commit
96ca1b6be3
@ -17,6 +17,8 @@
|
||||
|
||||
<!-- Changes that affect Black's preview style -->
|
||||
|
||||
- Remove parentheses around sole list items (#4312)
|
||||
|
||||
### Configuration
|
||||
|
||||
<!-- Changes to how Black can be configured -->
|
||||
|
@ -38,6 +38,9 @@ Currently, the following features are included in the preview style:
|
||||
blocks when the line is too long
|
||||
- `pep646_typed_star_arg_type_var_tuple`: fix type annotation spacing between * and more
|
||||
complex type variable tuple (i.e. `def fn(*args: *tuple[*Ts, T]) -> None: pass`)
|
||||
- `remove_lone_list_item_parens`: remove redundant parentheses around lone list items
|
||||
(depends on unstable `hug_parens_with_braces_and_square_brackets` feature in some
|
||||
cases)
|
||||
|
||||
(labels/unstable-features)=
|
||||
|
||||
|
@ -507,6 +507,22 @@ def visit_NUMBER(self, leaf: Leaf) -> Iterator[Line]:
|
||||
normalize_numeric_literal(leaf)
|
||||
yield from self.visit_default(leaf)
|
||||
|
||||
def visit_atom(self, node: Node) -> Iterator[Line]:
|
||||
"""Visit any atom"""
|
||||
if (
|
||||
Preview.remove_lone_list_item_parens in self.mode
|
||||
and len(node.children) == 3
|
||||
):
|
||||
first = node.children[0]
|
||||
last = node.children[-1]
|
||||
if (first.type == token.LSQB and last.type == token.RSQB) or (
|
||||
first.type == token.LBRACE and last.type == token.RBRACE
|
||||
):
|
||||
# Lists or sets of one item
|
||||
maybe_make_parens_invisible_in_atom(node.children[1], parent=node)
|
||||
|
||||
yield from self.visit_default(node)
|
||||
|
||||
def visit_fstring(self, node: Node) -> Iterator[Line]:
|
||||
# currently we don't want to format and split f-strings at all.
|
||||
string_leaf = fstring_to_string(node)
|
||||
@ -1643,9 +1659,6 @@ def maybe_make_parens_invisible_in_atom(
|
||||
not is_type_ignore_comment_string(middle.prefix.strip())
|
||||
):
|
||||
first.value = ""
|
||||
if first.prefix.strip():
|
||||
# Preserve comments before first paren
|
||||
middle.prefix = first.prefix + middle.prefix
|
||||
last.value = ""
|
||||
maybe_make_parens_invisible_in_atom(
|
||||
middle,
|
||||
@ -1657,6 +1670,13 @@ def maybe_make_parens_invisible_in_atom(
|
||||
# Strip the invisible parens from `middle` by replacing
|
||||
# it with the child in-between the invisible parens
|
||||
middle.replace(middle.children[1])
|
||||
|
||||
if middle.children[0].prefix.strip():
|
||||
# Preserve comments before first paren
|
||||
middle.children[1].prefix = (
|
||||
middle.children[0].prefix + middle.children[1].prefix
|
||||
)
|
||||
|
||||
if middle.children[-1].prefix.strip():
|
||||
# Preserve comments before last paren
|
||||
last.prefix = middle.children[-1].prefix + last.prefix
|
||||
|
@ -210,6 +210,9 @@ class Preview(Enum):
|
||||
docstring_check_for_newline = auto()
|
||||
remove_redundant_guard_parens = auto()
|
||||
parens_for_long_if_clauses_in_case_block = auto()
|
||||
# NOTE: remove_lone_list_item_parens requires
|
||||
# hug_parens_with_braces_and_square_brackets to remove parens in some cases
|
||||
remove_lone_list_item_parens = auto()
|
||||
pep646_typed_star_arg_type_var_tuple = auto()
|
||||
|
||||
|
||||
|
@ -91,6 +91,7 @@
|
||||
"docstring_check_for_newline",
|
||||
"remove_redundant_guard_parens",
|
||||
"parens_for_long_if_clauses_in_case_block",
|
||||
"remove_lone_list_item_parens",
|
||||
"pep646_typed_star_arg_type_var_tuple"
|
||||
]
|
||||
},
|
||||
|
158
tests/data/cases/preview_remove_lone_list_item_parens.py
Normal file
158
tests/data/cases/preview_remove_lone_list_item_parens.py
Normal file
@ -0,0 +1,158 @@
|
||||
# flags: --preview
|
||||
items = [(123)]
|
||||
items = [(True)]
|
||||
items = [(((((True)))))]
|
||||
items = [(((((True,)))))]
|
||||
items = [((((()))))]
|
||||
items = [(x for x in [1])]
|
||||
items = {(123)}
|
||||
items = {(True)}
|
||||
items = {(((((True)))))}
|
||||
|
||||
# Requires `hug_parens_with_braces_and_square_brackets` unstable style to remove parentheses
|
||||
# around multiline values
|
||||
items = [
|
||||
(
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
)
|
||||
]
|
||||
items = [
|
||||
(
|
||||
{"key1": "val1", "key2": "val2"}
|
||||
if some_var == ""
|
||||
else {"key": "val"}
|
||||
)
|
||||
]
|
||||
|
||||
# Comments should not cause crashes
|
||||
items = [
|
||||
( # comment
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
)
|
||||
]
|
||||
items = [
|
||||
(
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
) # comment
|
||||
]
|
||||
|
||||
items = [ # comment
|
||||
(
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
)
|
||||
]
|
||||
items = [
|
||||
(
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
)
|
||||
] # comment
|
||||
|
||||
items = [
|
||||
(
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"} # comment
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
)
|
||||
]
|
||||
|
||||
items = [ # comment
|
||||
( # comment
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
)
|
||||
]
|
||||
items = [
|
||||
(
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
) # comment
|
||||
] # comment
|
||||
|
||||
|
||||
# output
|
||||
items = [123]
|
||||
items = [True]
|
||||
items = [True]
|
||||
items = [(True,)]
|
||||
items = [()]
|
||||
items = [(x for x in [1])]
|
||||
items = {123}
|
||||
items = {True}
|
||||
items = {True}
|
||||
|
||||
# Requires `hug_parens_with_braces_and_square_brackets` unstable style to remove parentheses
|
||||
# around multiline values
|
||||
items = [
|
||||
(
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
)
|
||||
]
|
||||
items = [{"key1": "val1", "key2": "val2"} if some_var == "" else {"key": "val"}]
|
||||
|
||||
# Comments should not cause crashes
|
||||
items = [
|
||||
( # comment
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
)
|
||||
]
|
||||
items = [
|
||||
(
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
) # comment
|
||||
]
|
||||
|
||||
items = [ # comment
|
||||
(
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
)
|
||||
]
|
||||
items = [
|
||||
(
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
)
|
||||
] # comment
|
||||
|
||||
items = [
|
||||
(
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"} # comment
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
)
|
||||
]
|
||||
|
||||
items = [ # comment
|
||||
( # comment
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
)
|
||||
]
|
||||
items = [
|
||||
(
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
) # comment
|
||||
] # comment
|
@ -0,0 +1,246 @@
|
||||
# flags: --unstable
|
||||
items = [(x for x in [1])]
|
||||
|
||||
items = [
|
||||
(
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
)
|
||||
]
|
||||
items = [
|
||||
(
|
||||
{"key1": "val1", "key2": "val2"}
|
||||
if some_var == ""
|
||||
else {"key": "val"}
|
||||
)
|
||||
]
|
||||
items = [
|
||||
(
|
||||
"123456890123457890123468901234567890"
|
||||
if some_var == "long strings"
|
||||
else "123467890123467890"
|
||||
)
|
||||
]
|
||||
items = [
|
||||
(
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
and some_var == "long strings"
|
||||
and {"key": "val"}
|
||||
)
|
||||
]
|
||||
items = [
|
||||
(
|
||||
"123456890123457890123468901234567890"
|
||||
and some_var == "long strings"
|
||||
and "123467890123467890"
|
||||
)
|
||||
]
|
||||
items = [
|
||||
(
|
||||
long_variable_name
|
||||
and even_longer_variable_name
|
||||
and yet_another_very_long_variable_name
|
||||
)
|
||||
]
|
||||
|
||||
# Shouldn't remove trailing commas
|
||||
items = [
|
||||
(
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
),
|
||||
]
|
||||
items = [
|
||||
(
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
and some_var == "long strings"
|
||||
and {"key": "val"}
|
||||
),
|
||||
]
|
||||
items = [
|
||||
(
|
||||
"123456890123457890123468901234567890"
|
||||
and some_var == "long strings"
|
||||
and "123467890123467890"
|
||||
),
|
||||
]
|
||||
items = [
|
||||
(
|
||||
long_variable_name
|
||||
and even_longer_variable_name
|
||||
and yet_another_very_long_variable_name
|
||||
),
|
||||
]
|
||||
|
||||
# Shouldn't add parentheses
|
||||
items = [
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
]
|
||||
items = [{"key1": "val1", "key2": "val2"} if some_var == "" else {"key": "val"}]
|
||||
|
||||
# Shouldn't crash with comments
|
||||
items = [
|
||||
( # comment
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
)
|
||||
]
|
||||
items = [
|
||||
(
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
) # comment
|
||||
]
|
||||
|
||||
items = [ # comment
|
||||
(
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
)
|
||||
]
|
||||
items = [
|
||||
(
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
)
|
||||
] # comment
|
||||
|
||||
items = [
|
||||
(
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"} # comment
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
)
|
||||
]
|
||||
|
||||
items = [ # comment
|
||||
( # comment
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
)
|
||||
]
|
||||
items = [
|
||||
(
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
) # comment
|
||||
] # comment
|
||||
|
||||
|
||||
# output
|
||||
items = [(x for x in [1])]
|
||||
|
||||
items = [
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
]
|
||||
items = [{"key1": "val1", "key2": "val2"} if some_var == "" else {"key": "val"}]
|
||||
items = [
|
||||
"123456890123457890123468901234567890"
|
||||
if some_var == "long strings"
|
||||
else "123467890123467890"
|
||||
]
|
||||
items = [
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
and some_var == "long strings"
|
||||
and {"key": "val"}
|
||||
]
|
||||
items = [
|
||||
"123456890123457890123468901234567890"
|
||||
and some_var == "long strings"
|
||||
and "123467890123467890"
|
||||
]
|
||||
items = [
|
||||
long_variable_name
|
||||
and even_longer_variable_name
|
||||
and yet_another_very_long_variable_name
|
||||
]
|
||||
|
||||
# Shouldn't remove trailing commas
|
||||
items = [
|
||||
(
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
),
|
||||
]
|
||||
items = [
|
||||
(
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
and some_var == "long strings"
|
||||
and {"key": "val"}
|
||||
),
|
||||
]
|
||||
items = [
|
||||
(
|
||||
"123456890123457890123468901234567890"
|
||||
and some_var == "long strings"
|
||||
and "123467890123467890"
|
||||
),
|
||||
]
|
||||
items = [
|
||||
(
|
||||
long_variable_name
|
||||
and even_longer_variable_name
|
||||
and yet_another_very_long_variable_name
|
||||
),
|
||||
]
|
||||
|
||||
# Shouldn't add parentheses
|
||||
items = [
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
]
|
||||
items = [{"key1": "val1", "key2": "val2"} if some_var == "" else {"key": "val"}]
|
||||
|
||||
# Shouldn't crash with comments
|
||||
items = [ # comment
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
]
|
||||
items = [
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
] # comment
|
||||
|
||||
items = [ # comment
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
]
|
||||
items = [
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
] # comment
|
||||
|
||||
items = [
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"} # comment
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
]
|
||||
|
||||
items = [ # comment # comment
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
]
|
||||
items = [
|
||||
{"key1": "val1", "key2": "val2", "key3": "val3"}
|
||||
if some_var == "long strings"
|
||||
else {"key": "val"}
|
||||
] # comment # comment
|
Loading…
Reference in New Issue
Block a user