Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strip trailing commas in subscripts with -C #3209

Merged
merged 5 commits into from Aug 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES.md
Expand Up @@ -24,6 +24,8 @@
this is invalid. This was a bug introduced in version 22.6.0. (#3166)
- `--skip-string-normalization` / `-S` now prevents docstring prefixes from being
normalized as expected (#3168)
- When using `--skip-magic-trailing-comma` or `-C`, trailing commas are stripped from
subscript expressions with more than 1 element (#3209)

### _Blackd_

Expand Down
18 changes: 17 additions & 1 deletion src/black/lines.py
Expand Up @@ -273,6 +273,8 @@ def has_magic_trailing_comma(
- it's not a single-element subscript
Additionally, if ensure_removable:
- it's not from square bracket indexing
(specifically, single-element square bracket indexing with
Preview.skip_magic_trailing_comma_in_subscript)
"""
if not (
closing.type in CLOSING_BRACKETS
Expand Down Expand Up @@ -301,8 +303,22 @@ def has_magic_trailing_comma(

if not ensure_removable:
return True

comma = self.leaves[-1]
return bool(comma.parent and comma.parent.type == syms.listmaker)
if comma.parent is None:
return False
if Preview.skip_magic_trailing_comma_in_subscript in self.mode:
return (
comma.parent.type != syms.subscriptlist
or closing.opening_bracket is None
or not is_one_sequence_between(
closing.opening_bracket,
closing,
self.leaves,
brackets=(token.LSQB, token.RSQB),
)
)
return comma.parent.type == syms.listmaker

if self.is_import:
return True
Expand Down
1 change: 1 addition & 0 deletions src/black/mode.py
Expand Up @@ -151,6 +151,7 @@ class Preview(Enum):
remove_block_trailing_newline = auto()
remove_redundant_parens = auto()
string_processing = auto()
skip_magic_trailing_comma_in_subscript = auto()


class Deprecated(UserWarning):
Expand Down
34 changes: 34 additions & 0 deletions tests/data/preview/skip_magic_trailing_comma.py
@@ -0,0 +1,34 @@
# We should not remove the trailing comma in a single-element subscript.
a: tuple[int,]
b = tuple[int,]

# But commas in multiple element subscripts should be removed.
c: tuple[int, int,]
d = tuple[int, int,]

# Remove commas for non-subscripts.
small_list = [1,]
list_of_types = [tuple[int,],]
small_set = {1,}
set_of_types = {tuple[int,],}

# Except single element tuples
small_tuple = (1,)

# output
# We should not remove the trailing comma in a single-element subscript.
a: tuple[int,]
b = tuple[int,]

# But commas in multiple element subscripts should be removed.
c: tuple[int, int]
d = tuple[int, int]

# Remove commas for non-subscripts.
small_list = [1]
list_of_types = [tuple[int,]]
small_set = {1}
set_of_types = {tuple[int,]}

# Except single element tuples
small_tuple = (1,)
7 changes: 6 additions & 1 deletion tests/test_format.py
Expand Up @@ -36,7 +36,12 @@ def test_simple_format(filename: str) -> None:

@pytest.mark.parametrize("filename", all_data_cases("preview"))
def test_preview_format(filename: str) -> None:
check_file("preview", filename, black.Mode(preview=True))
magic_trailing_comma = filename != "skip_magic_trailing_comma"
check_file(
"preview",
filename,
black.Mode(preview=True, magic_trailing_comma=magic_trailing_comma),
)


@pytest.mark.parametrize("filename", all_data_cases("preview_39"))
Expand Down