Avoid magic-trailing-comma in single-element subscripts (#2942)
Closes #2918.
This commit is contained in:
parent
062b54931d
commit
3800ebd81d
@ -15,6 +15,7 @@
|
||||
<!-- Changes that affect Black's preview style -->
|
||||
|
||||
- Code cell separators `#%%` are now standardised to `# %%` (#2919)
|
||||
- Avoid magic-trailing-comma in single-element subscripts (#2942)
|
||||
|
||||
### _Blackd_
|
||||
|
||||
|
@ -8,7 +8,12 @@
|
||||
from black.nodes import WHITESPACE, RARROW, STATEMENT, STANDALONE_COMMENT
|
||||
from black.nodes import ASSIGNMENTS, OPENING_BRACKETS, CLOSING_BRACKETS
|
||||
from black.nodes import Visitor, syms, is_arith_like, ensure_visible
|
||||
from black.nodes import is_docstring, is_empty_tuple, is_one_tuple, is_one_tuple_between
|
||||
from black.nodes import (
|
||||
is_docstring,
|
||||
is_empty_tuple,
|
||||
is_one_tuple,
|
||||
is_one_sequence_between,
|
||||
)
|
||||
from black.nodes import is_name_token, is_lpar_token, is_rpar_token
|
||||
from black.nodes import is_walrus_assignment, is_yield, is_vararg, is_multiline_string
|
||||
from black.nodes import is_stub_suite, is_stub_body, is_atom_with_invisible_parens
|
||||
@ -973,7 +978,7 @@ def generate_trailers_to_omit(line: Line, line_length: int) -> Iterator[Set[Leaf
|
||||
prev
|
||||
and prev.type == token.COMMA
|
||||
and leaf.opening_bracket is not None
|
||||
and not is_one_tuple_between(
|
||||
and not is_one_sequence_between(
|
||||
leaf.opening_bracket, leaf, line.leaves
|
||||
)
|
||||
):
|
||||
@ -1001,7 +1006,7 @@ def generate_trailers_to_omit(line: Line, line_length: int) -> Iterator[Set[Leaf
|
||||
prev
|
||||
and prev.type == token.COMMA
|
||||
and leaf.opening_bracket is not None
|
||||
and not is_one_tuple_between(leaf.opening_bracket, leaf, line.leaves)
|
||||
and not is_one_sequence_between(leaf.opening_bracket, leaf, line.leaves)
|
||||
):
|
||||
# Never omit bracket pairs with trailing commas.
|
||||
# We need to explode on those.
|
||||
|
@ -17,12 +17,12 @@
|
||||
from blib2to3.pgen2 import token
|
||||
|
||||
from black.brackets import BracketTracker, DOT_PRIORITY
|
||||
from black.mode import Mode
|
||||
from black.mode import Mode, Preview
|
||||
from black.nodes import STANDALONE_COMMENT, TEST_DESCENDANTS
|
||||
from black.nodes import BRACKETS, OPENING_BRACKETS, CLOSING_BRACKETS
|
||||
from black.nodes import syms, whitespace, replace_child, child_towards
|
||||
from black.nodes import is_multiline_string, is_import, is_type_comment
|
||||
from black.nodes import is_one_tuple_between
|
||||
from black.nodes import is_one_sequence_between
|
||||
|
||||
# types
|
||||
T = TypeVar("T")
|
||||
@ -254,6 +254,7 @@ def has_magic_trailing_comma(
|
||||
"""Return True if we have a magic trailing comma, that is when:
|
||||
- there's a trailing comma here
|
||||
- it's not a one-tuple
|
||||
- it's not a single-element subscript
|
||||
Additionally, if ensure_removable:
|
||||
- it's not from square bracket indexing
|
||||
"""
|
||||
@ -268,6 +269,20 @@ def has_magic_trailing_comma(
|
||||
return True
|
||||
|
||||
if closing.type == token.RSQB:
|
||||
if (
|
||||
Preview.one_element_subscript in self.mode
|
||||
and closing.parent
|
||||
and closing.parent.type == syms.trailer
|
||||
and closing.opening_bracket
|
||||
and is_one_sequence_between(
|
||||
closing.opening_bracket,
|
||||
closing,
|
||||
self.leaves,
|
||||
brackets=(token.LSQB, token.RSQB),
|
||||
)
|
||||
):
|
||||
return False
|
||||
|
||||
if not ensure_removable:
|
||||
return True
|
||||
comma = self.leaves[-1]
|
||||
@ -276,7 +291,7 @@ def has_magic_trailing_comma(
|
||||
if self.is_import:
|
||||
return True
|
||||
|
||||
if closing.opening_bracket is not None and not is_one_tuple_between(
|
||||
if closing.opening_bracket is not None and not is_one_sequence_between(
|
||||
closing.opening_bracket, closing, self.leaves
|
||||
):
|
||||
return True
|
||||
|
@ -127,6 +127,7 @@ class Preview(Enum):
|
||||
"""Individual preview style features."""
|
||||
|
||||
string_processing = auto()
|
||||
one_element_subscript = auto()
|
||||
|
||||
|
||||
class Deprecated(UserWarning):
|
||||
@ -162,9 +163,7 @@ def __contains__(self, feature: Preview) -> bool:
|
||||
"""
|
||||
if feature is Preview.string_processing:
|
||||
return self.preview or self.experimental_string_processing
|
||||
# TODO: Remove type ignore comment once preview contains more features
|
||||
# than just ESP
|
||||
return self.preview # type: ignore
|
||||
return self.preview
|
||||
|
||||
def get_cache_key(self) -> str:
|
||||
if self.target_versions:
|
||||
|
@ -9,6 +9,7 @@
|
||||
List,
|
||||
Optional,
|
||||
Set,
|
||||
Tuple,
|
||||
TypeVar,
|
||||
Union,
|
||||
)
|
||||
@ -559,9 +560,14 @@ def is_one_tuple(node: LN) -> bool:
|
||||
)
|
||||
|
||||
|
||||
def is_one_tuple_between(opening: Leaf, closing: Leaf, leaves: List[Leaf]) -> bool:
|
||||
"""Return True if content between `opening` and `closing` looks like a one-tuple."""
|
||||
if opening.type != token.LPAR and closing.type != token.RPAR:
|
||||
def is_one_sequence_between(
|
||||
opening: Leaf,
|
||||
closing: Leaf,
|
||||
leaves: List[Leaf],
|
||||
brackets: Tuple[int, int] = (token.LPAR, token.RPAR),
|
||||
) -> bool:
|
||||
"""Return True if content between `opening` and `closing` is a one-sequence."""
|
||||
if (opening.type, closing.type) != brackets:
|
||||
return False
|
||||
|
||||
depth = closing.bracket_depth + 1
|
||||
|
36
tests/data/one_element_subscript.py
Normal file
36
tests/data/one_element_subscript.py
Normal file
@ -0,0 +1,36 @@
|
||||
# We should not treat the trailing comma
|
||||
# in a single-element subscript.
|
||||
a: tuple[int,]
|
||||
b = tuple[int,]
|
||||
|
||||
# The magic comma still applies to multi-element subscripts.
|
||||
c: tuple[int, int,]
|
||||
d = tuple[int, int,]
|
||||
|
||||
# Magic commas still work as expected for non-subscripts.
|
||||
small_list = [1,]
|
||||
list_of_types = [tuple[int,],]
|
||||
|
||||
# output
|
||||
# We should not treat the trailing comma
|
||||
# in a single-element subscript.
|
||||
a: tuple[int,]
|
||||
b = tuple[int,]
|
||||
|
||||
# The magic comma still applies to multi-element subscripts.
|
||||
c: tuple[
|
||||
int,
|
||||
int,
|
||||
]
|
||||
d = tuple[
|
||||
int,
|
||||
int,
|
||||
]
|
||||
|
||||
# Magic commas still work as expected for non-subscripts.
|
||||
small_list = [
|
||||
1,
|
||||
]
|
||||
list_of_types = [
|
||||
tuple[int,],
|
||||
]
|
@ -80,6 +80,7 @@
|
||||
"long_strings__edge_case",
|
||||
"long_strings__regression",
|
||||
"percent_precedence",
|
||||
"one_element_subscript",
|
||||
]
|
||||
|
||||
SOURCES: List[str] = [
|
||||
|
Loading…
Reference in New Issue
Block a user