Update Black tests (#20794)

Summary
--

```shell
git clone git@github.com:psf/black.git ../other/black
crates/ruff_python_formatter/resources/test/fixtures/import_black_tests.py ../other/black
```

Then ran our tests and accepted the snapshots

I had to make a small fix to our tuple normalization logic for `del`
statements
in the second commit, otherwise the tests were panicking at a changed
AST. I
think the new implementation is closer to the intention described in the
nearby
comment anyway, though.

The first commit adds the new Python, settings, and `.expect` files, the
next three commits make some small
fixes to help get the tests running, and then the fifth commit accepts
all but one of the new snapshots. The last commit includes the new
unsupported syntax error for one f-string example, tracked in #20774.

Test Plan
--

Newly imported tests. I went through all of the new snapshots and added
review comments below. I think they're all expected, except a few cases
I wasn't 100% sure about.
This commit is contained in:
Brent Westbrook 2025-10-14 10:14:59 -04:00 committed by GitHub
parent 9090aead0f
commit 1ed9b215b9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
123 changed files with 6607 additions and 343 deletions

View file

@ -0,0 +1,7 @@
# regression test for #1765
class Foo:
def foo(self):
if True:
content_ids: Mapping[
str, Optional[ContentId]
] = self.publisher_content_store.store_config_contents(files)

View file

@ -0,0 +1,7 @@
# regression test for #1765
class Foo:
def foo(self):
if True:
content_ids: Mapping[str, Optional[ContentId]] = (
self.publisher_content_store.store_config_contents(files)
)

View file

@ -1 +1 @@
{"target_version": "3.10"}
{"target_version": "3.10"}

View file

@ -0,0 +1,35 @@
# long variable name
this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = 0
this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = 1 # with a comment
this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = [
1, 2, 3
]
this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = function()
this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = function(
arg1, arg2, arg3
)
this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = function(
[1, 2, 3], arg1, [1, 2, 3], arg2, [1, 2, 3], arg3
)
# long function name
normal_name = but_the_function_name_is_now_ridiculously_long_and_it_is_still_super_annoying()
normal_name = but_the_function_name_is_now_ridiculously_long_and_it_is_still_super_annoying(
arg1, arg2, arg3
)
normal_name = but_the_function_name_is_now_ridiculously_long_and_it_is_still_super_annoying(
[1, 2, 3], arg1, [1, 2, 3], arg2, [1, 2, 3], arg3
)
string_variable_name = (
"a string that is waaaaaaaayyyyyyyy too long, even in parens, there's nothing you can do" # noqa
)
for key in """
hostname
port
username
""".split():
if key in self.connect_kwargs:
raise ValueError(err.format(key))
concatenated_strings = "some strings that are " "concatenated implicitly, so if you put them on separate " "lines it will fit"
del concatenated_strings, string_variable_name, normal_function_name, normal_name, need_more_to_make_the_line_long_enough
del ([], name_1, name_2), [(), [], name_4, name_3], name_1[[name_2 for name_1 in name_0]]
del (),

View file

@ -0,0 +1,61 @@
# long variable name
this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = (
0
)
this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = (
1 # with a comment
)
this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = [
1,
2,
3,
]
this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = (
function()
)
this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = function(
arg1, arg2, arg3
)
this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = function(
[1, 2, 3], arg1, [1, 2, 3], arg2, [1, 2, 3], arg3
)
# long function name
normal_name = (
but_the_function_name_is_now_ridiculously_long_and_it_is_still_super_annoying()
)
normal_name = (
but_the_function_name_is_now_ridiculously_long_and_it_is_still_super_annoying(
arg1, arg2, arg3
)
)
normal_name = (
but_the_function_name_is_now_ridiculously_long_and_it_is_still_super_annoying(
[1, 2, 3], arg1, [1, 2, 3], arg2, [1, 2, 3], arg3
)
)
string_variable_name = "a string that is waaaaaaaayyyyyyyy too long, even in parens, there's nothing you can do" # noqa
for key in """
hostname
port
username
""".split():
if key in self.connect_kwargs:
raise ValueError(err.format(key))
concatenated_strings = (
"some strings that are "
"concatenated implicitly, so if you put them on separate "
"lines it will fit"
)
del (
concatenated_strings,
string_variable_name,
normal_function_name,
normal_name,
need_more_to_make_the_line_long_enough,
)
del (
([], name_1, name_2),
[(), [], name_4, name_3],
name_1[[name_2 for name_1 in name_0]],
)
del ((),)

View file

@ -1 +1 @@
{"target_version": "3.8"}
{"target_version": "3.8"}

View file

@ -82,3 +82,9 @@ async def func():
argument1, argument2, argument3="some_value"
):
pass
# don't remove the brackets here, it changes the meaning of the code.
with (x, y) as z:
pass

View file

@ -83,3 +83,8 @@ async def func():
some_other_function(argument1, argument2, argument3="some_value"),
):
pass
# don't remove the brackets here, it changes the meaning of the code.
with (x, y) as z:
pass

View file

@ -0,0 +1,3 @@
"""
87 characters ............................................................................
"""

View file

@ -0,0 +1,3 @@
"""
87 characters ............................................................................
"""

View file

@ -0,0 +1,8 @@
def foo(): return "mock" # fmt: skip
if True: print("yay") # fmt: skip
for i in range(10): print(i) # fmt: skip
j = 1 # fmt: skip
while j < 10: j += 1 # fmt: skip
b = [c for c in "A very long string that would normally generate some kind of collapse, since it is this long"] # fmt: skip

View file

@ -0,0 +1,8 @@
def foo(): return "mock" # fmt: skip
if True: print("yay") # fmt: skip
for i in range(10): print(i) # fmt: skip
j = 1 # fmt: skip
while j < 10: j += 1 # fmt: skip
b = [c for c in "A very long string that would normally generate some kind of collapse, since it is this long"] # fmt: skip

View file

@ -0,0 +1,6 @@
def foo():
pass
# comment 1 # fmt: skip
# comment 2

View file

@ -0,0 +1,6 @@
def foo():
pass
# comment 1 # fmt: skip
# comment 2

View file

@ -0,0 +1,15 @@
x = "\x1F"
x = "\\x1B"
x = "\\\x1B"
x = "\U0001F60E"
x = "\u0001F60E"
x = r"\u0001F60E"
x = "don't format me"
x = "\xA3"
x = "\u2717"
x = "\uFaCe"
x = "\N{ox}\N{OX}"
x = "\N{lAtIn smaLL letteR x}"
x = "\N{CYRILLIC small LETTER BYELORUSSIAN-UKRAINIAN I}"
x = b"\x1Fdon't byte"
x = rb"\x1Fdon't format"

View file

@ -0,0 +1,15 @@
x = "\x1f"
x = "\\x1B"
x = "\\\x1b"
x = "\U0001f60e"
x = "\u0001F60E"
x = r"\u0001F60E"
x = "don't format me"
x = "\xa3"
x = "\u2717"
x = "\uface"
x = "\N{OX}\N{OX}"
x = "\N{LATIN SMALL LETTER X}"
x = "\N{CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I}"
x = b"\x1fdon't byte"
x = rb"\x1Fdon't format"

View file

@ -1 +0,0 @@
{"target_version": "3.12"}

View file

@ -0,0 +1,34 @@
# Regression tests for long f-strings, including examples from issue #3623
a = (
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
f'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"{"b"}"'
)
a = (
f'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"{"b"}"'
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
)
a = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + \
f'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"{"b"}"'
a = f'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"{"b"}"' + \
f'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"{"b"}"'
a = (
f'bbbbbbb"{"b"}"'
'aaaaaaaa'
)
a = (
f'"{"b"}"'
)
a = (
f'\"{"b"}\"'
)
a = (
r'\"{"b"}\"'
)

View file

@ -0,0 +1,29 @@
# Regression tests for long f-strings, including examples from issue #3623
a = (
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
f'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"{"b"}"'
)
a = (
f'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"{"b"}"'
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
)
a = (
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ f'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"{"b"}"'
)
a = (
f'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"{"b"}"'
+ f'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"{"b"}"'
)
a = f'bbbbbbb"{"b"}"' "aaaaaaaa"
a = f'"{"b"}"'
a = f'"{"b"}"'
a = r'\"{"b"}\"'

View file

@ -1 +1 @@
{"preview": "enabled", "target_version": "3.10"}
{"target_version": "3.10"}

View file

@ -0,0 +1 @@
{"target_version": "3.12"}

View file

@ -0,0 +1,133 @@
def plain[T, B](a: T, b: T) -> T:
return a
def arg_magic[T, B](a: T, b: T,) -> T:
return a
def type_param_magic[T, B,](a: T, b: T) -> T:
return a
def both_magic[T, B,](a: T, b: T,) -> T:
return a
def plain_multiline[
T,
B
](
a: T,
b: T
) -> T:
return a
def arg_magic_multiline[
T,
B
](
a: T,
b: T,
) -> T:
return a
def type_param_magic_multiline[
T,
B,
](
a: T,
b: T
) -> T:
return a
def both_magic_multiline[
T,
B,
](
a: T,
b: T,
) -> T:
return a
def plain_mixed1[
T,
B
](a: T, b: T) -> T:
return a
def plain_mixed2[T, B](
a: T,
b: T
) -> T:
return a
def arg_magic_mixed1[
T,
B
](a: T, b: T,) -> T:
return a
def arg_magic_mixed2[T, B](
a: T,
b: T,
) -> T:
return a
def type_param_magic_mixed1[
T,
B,
](a: T, b: T) -> T:
return a
def type_param_magic_mixed2[T, B,](
a: T,
b: T
) -> T:
return a
def both_magic_mixed1[
T,
B,
](a: T, b: T,) -> T:
return a
def both_magic_mixed2[T, B,](
a: T,
b: T,
) -> T:
return a
def something_something_function[
T: Model
](param: list[int], other_param: type[T], *, some_other_param: bool = True) -> QuerySet[
T
]:
pass
def func[A_LOT_OF_GENERIC_TYPES: AreBeingDefinedHere, LIKE_THIS, AND_THIS, ANOTHER_ONE, AND_YET_ANOTHER_ONE: ThisOneHasTyping](a: T, b: T, c: T, d: T, e: T, f: T, g: T, h: T, i: T, j: T, k: T, l: T, m: T, n: T, o: T, p: T) -> T:
return a
def with_random_comments[
Z
# bye
]():
return a
def func[
T, # comment
U # comment
,
Z: # comment
int
](): pass
def func[
T, # comment but it's long so it doesn't just move to the end of the line
U # comment comment comm comm ent ent
,
Z: # comment ent ent comm comm comment
int
](): pass

View file

@ -0,0 +1,170 @@
def plain[T, B](a: T, b: T) -> T:
return a
def arg_magic[T, B](
a: T,
b: T,
) -> T:
return a
def type_param_magic[
T,
B,
](
a: T, b: T
) -> T:
return a
def both_magic[
T,
B,
](
a: T,
b: T,
) -> T:
return a
def plain_multiline[T, B](a: T, b: T) -> T:
return a
def arg_magic_multiline[T, B](
a: T,
b: T,
) -> T:
return a
def type_param_magic_multiline[
T,
B,
](
a: T, b: T
) -> T:
return a
def both_magic_multiline[
T,
B,
](
a: T,
b: T,
) -> T:
return a
def plain_mixed1[T, B](a: T, b: T) -> T:
return a
def plain_mixed2[T, B](a: T, b: T) -> T:
return a
def arg_magic_mixed1[T, B](
a: T,
b: T,
) -> T:
return a
def arg_magic_mixed2[T, B](
a: T,
b: T,
) -> T:
return a
def type_param_magic_mixed1[
T,
B,
](
a: T, b: T
) -> T:
return a
def type_param_magic_mixed2[
T,
B,
](
a: T, b: T
) -> T:
return a
def both_magic_mixed1[
T,
B,
](
a: T,
b: T,
) -> T:
return a
def both_magic_mixed2[
T,
B,
](
a: T,
b: T,
) -> T:
return a
def something_something_function[T: Model](
param: list[int], other_param: type[T], *, some_other_param: bool = True
) -> QuerySet[T]:
pass
def func[
A_LOT_OF_GENERIC_TYPES: AreBeingDefinedHere,
LIKE_THIS,
AND_THIS,
ANOTHER_ONE,
AND_YET_ANOTHER_ONE: ThisOneHasTyping,
](
a: T,
b: T,
c: T,
d: T,
e: T,
f: T,
g: T,
h: T,
i: T,
j: T,
k: T,
l: T,
m: T,
n: T,
o: T,
p: T,
) -> T:
return a
def with_random_comments[
Z
# bye
]():
return a
def func[T, U, Z: int](): # comment # comment # comment
pass
def func[
T, # comment but it's long so it doesn't just move to the end of the line
U, # comment comment comm comm ent ent
Z: int, # comment ent ent comm comm comment
]():
pass

View file

@ -6,7 +6,7 @@ def foo2(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, parame
def foo3(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, parameter_6, parameter_7): pass
def foo4(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, parameter_6, parameter_7): pass
# Adding some unformatted code covering a wide range of syntaxes.
# Adding some unformated code covering a wide range of syntaxes.
if True:
# Incorrectly indented prefix comments.

View file

@ -28,7 +28,7 @@ def foo3(
def foo4(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, parameter_6, parameter_7): pass
# Adding some unformatted code covering a wide range of syntaxes.
# Adding some unformated code covering a wide range of syntaxes.
if True:
# Incorrectly indented prefix comments.

View file

@ -0,0 +1,8 @@
# flags: --line-ranges=6-7
class Foo:
@overload
def foo(): ...
def fox(self):
print()

View file

@ -0,0 +1,8 @@
# flags: --line-ranges=6-7
class Foo:
@overload
def foo(): ...
def fox(self):
print()

View file

@ -0,0 +1,28 @@
def func(
arg1,
arg2,
) -> Set["this_is_a_very_long_module_name.AndAVeryLongClasName"
".WithAVeryVeryVeryVeryVeryLongSubClassName"]:
pass
def func(
argument: (
"VeryLongClassNameWithAwkwardGenericSubtype[int] |"
"VeryLongClassNameWithAwkwardGenericSubtype[str]"
),
) -> (
"VeryLongClassNameWithAwkwardGenericSubtype[int] |"
"VeryLongClassNameWithAwkwardGenericSubtype[str]"
):
pass
def func(
argument: (
"int |"
"str"
),
) -> Set["int |"
" str"]:
pass

View file

@ -0,0 +1,26 @@
def func(
arg1,
arg2,
) -> Set[
"this_is_a_very_long_module_name.AndAVeryLongClasName"
".WithAVeryVeryVeryVeryVeryLongSubClassName"
]:
pass
def func(
argument: (
"VeryLongClassNameWithAwkwardGenericSubtype[int] |"
"VeryLongClassNameWithAwkwardGenericSubtype[str]"
),
) -> (
"VeryLongClassNameWithAwkwardGenericSubtype[int] |"
"VeryLongClassNameWithAwkwardGenericSubtype[str]"
):
pass
def func(
argument: "int |" "str",
) -> Set["int |" " str"]:
pass

View file

@ -1,6 +1,6 @@
"""I am a very helpful module docstring.
With trailing spaces (only removed with unify_docstring_detection on):
With trailing spaces:
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam,

View file

@ -1,6 +1,6 @@
"""I am a very helpful module docstring.
With trailing spaces (only removed with unify_docstring_detection on):
With trailing spaces:
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam,

View file

@ -0,0 +1,9 @@
#!/python
# regression test for #4762
"""
docstring
"""
from __future__ import annotations
import os

View file

@ -0,0 +1,10 @@
#!/python
# regression test for #4762
"""
docstring
"""
from __future__ import annotations
import os

View file

@ -25,5 +25,4 @@ class MultilineDocstringsAsWell:
class SingleQuotedDocstring:
"I'm a docstring but I don't even get triple quotes."

View file

@ -1 +1 @@
{"preview": "enabled", "target_version": "3.10"}
{"target_version": "3.10"}

View file

@ -19,7 +19,7 @@ z: (Short
z: (int) = 2.3
z: ((int)) = foo()
# In case I go for not enforcing parentheses, this might get improved at the same time
# In case I go for not enforcing parantheses, this might get improved at the same time
x = (
z
== 9999999999999999999999999999999999999999

View file

@ -28,7 +28,7 @@ z: Short | Short2 | Short3 | Short4 = 8
z: int = 2.3
z: int = foo()
# In case I go for not enforcing parentheses, this might get improved at the same time
# In case I go for not enforcing parantheses, this might get improved at the same time
x = (
z
== 9999999999999999999999999999999999999999

View file

@ -0,0 +1 @@
{"target_version": "3.11"}

View file

@ -0,0 +1,5 @@
def fn(*args: *tuple[*A, B]) -> None:
pass
fn.__annotations__

View file

@ -0,0 +1,5 @@
def fn(*args: *tuple[*A, B]) -> None:
pass
fn.__annotations__

View file

@ -13,3 +13,8 @@ f(a := b + c for c in range(10))
f((a := b + c for c in range(10)), x)
f(y=(a := b + c for c in range(10)))
f(x, (a := b + c for c in range(10)), y=z, **q)
# Don't remove parens when assignment expr is one of the exprs in a with statement
with x, (a := b):
pass

View file

@ -13,3 +13,8 @@ f(a := b + c for c in range(10))
f((a := b + c for c in range(10)), x)
f(y=(a := b + c for c in range(10)))
f(x, (a := b + c for c in range(10)), y=z, **q)
# Don't remove parens when assignment expr is one of the exprs in a with statement
with x, (a := b):
pass

View file

@ -73,8 +73,9 @@ x = f"a{2+2:=^{foo(x+y**2):something else}}b"
x = f"a{2+2:=^{foo(x+y**2):something else}one more}b"
f'{(abc:=10)}'
f"This is a really long string, but just make sure that you reflow fstrings {
2+2:d}"
f"""This is a really long string, but just make sure that you reflow fstrings {
2+2:d
}"""
f"This is a really long string, but just make sure that you reflow fstrings correctly {2+2:d}"
f"{2+2=}"

View file

@ -73,9 +73,9 @@ x = f"a{2+2:=^{foo(x+y**2):something else}}b"
x = f"a{2+2:=^{foo(x+y**2):something else}one more}b"
f"{(abc:=10)}"
f"This is a really long string, but just make sure that you reflow fstrings {
f"""This is a really long string, but just make sure that you reflow fstrings {
2+2:d
}"
}"""
f"This is a really long string, but just make sure that you reflow fstrings correctly {2+2:d}"
f"{2+2=}"

View file

@ -10,3 +10,12 @@ first_value, (m1, m2,), third_value = xxxxxx_yyyyyy_zzzzzz_wwwwww_uuuuuuu_vvvvvv
# Make when when the left side of assignment plus the opening paren "... = (" is
# exactly line length limit + 1, it won't be split like that.
xxxxxxxxx_yyy_zzzzzzzz[xx.xxxxxx(x_yyy_zzzzzz.xxxxx[0]), x_yyy_zzzzzz.xxxxxx(xxxx=1)] = 1
# Regression test for #1187
print(
dict(
a=1,
b=2 if some_kind_of_data is not None else some_other_kind_of_data, # some explanation of why this is actually necessary
c=3,
)
)

View file

@ -19,3 +19,14 @@
xxxxxxxxx_yyy_zzzzzzzz[
xx.xxxxxx(x_yyy_zzzzzz.xxxxx[0]), x_yyy_zzzzzz.xxxxxx(xxxx=1)
] = 1
# Regression test for #1187
print(
dict(
a=1,
b=(
2 if some_kind_of_data is not None else some_other_kind_of_data
), # some explanation of why this is actually necessary
c=3,
)
)

View file

@ -29,7 +29,6 @@ from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component
MyLovelyCompanyTeamProjectComponent as component, # DRY
)
result = 1 # look ma, no comment migration xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
result = 1 # look ma, no comment migration xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

View file

@ -0,0 +1 @@
f"{''=}" f'{""=}'

View file

@ -0,0 +1 @@
f"{''=}" f'{""=}'

View file

@ -0,0 +1,90 @@
from middleman.authentication import validate_oauth_token
logger = logging.getLogger(__name__)
# case 2 comment after import
from middleman.authentication import validate_oauth_token
#comment
logger = logging.getLogger(__name__)
# case 3 comment after import
from middleman.authentication import validate_oauth_token
# comment
logger = logging.getLogger(__name__)
from middleman.authentication import validate_oauth_token
logger = logging.getLogger(__name__)
# case 4 try catch with import after import
import os
import os
try:
import os
except Exception:
pass
try:
import os
def func():
a = 1
except Exception:
pass
# case 5 multiple imports
import os
import os
import os
import os
for i in range(10):
print(i)
# case 6 import in function
def func():
print()
import os
def func():
pass
print()
def func():
import os
a = 1
print()
def func():
import os
a = 1
print()
def func():
import os
a = 1
print()

View file

@ -0,0 +1,85 @@
from middleman.authentication import validate_oauth_token
logger = logging.getLogger(__name__)
# case 2 comment after import
from middleman.authentication import validate_oauth_token
# comment
logger = logging.getLogger(__name__)
# case 3 comment after import
from middleman.authentication import validate_oauth_token
# comment
logger = logging.getLogger(__name__)
from middleman.authentication import validate_oauth_token
logger = logging.getLogger(__name__)
# case 4 try catch with import after import
import os
import os
try:
import os
except Exception:
pass
try:
import os
def func():
a = 1
except Exception:
pass
# case 5 multiple imports
import os
import os
import os
import os
for i in range(10):
print(i)
# case 6 import in function
def func():
print()
import os
def func():
pass
print()
def func():
import os
a = 1
print()
def func():
import os
a = 1
print()
def func():
import os
a = 1
print()

View file

@ -1,3 +1,24 @@
x = {
"xx_xxxxx_xxxxxxxxxx_xxxxxxxxx_xx": (
"xx:xxxxxxxxxxxxxxxxx_xxxxx_xxxxxxx_xxxxxxxxxxx{xx}xxx_xxxxx_xxxxxxxxx_xxxxxxxxxxxx_xxxx"
)
}
x = {
"xx_xxxxx_xxxxxxxxxx_xxxxxxxxx_xx": (
"xx:xxxxxxxxxxxxxxxxx_xxxxx_xxxxxxx_xxxxxxxxxxx{xx}xxx_xxxxx_xxxxxxxxx_xxxxxxxxxxxx_xxxx"
),
}
x = {
"foo": bar,
"foo": bar,
"foo": (
xx_xxxxxxxxxxxxxxxxx_xxxxx_xxxxxxx_xxxxxxxxxxxxxx_xxxxx_xxxxxxxxx_xxxxxxxxxxxx_xxxx
),
}
x = {
"xx_xxxxx_xxxxxxxxxx_xxxxxxxxx_xx": "xx:xxxxxxxxxxxxxxxxx_xxxxx_xxxxxxx_xxxxxxxxxx"
}
my_dict = {
"something_something":
r"Lorem ipsum dolor sit amet, an sed convenire eloquentiam \t"
@ -5,23 +26,90 @@ my_dict = {
r"signiferumque, duo ea vocibus consetetur scriptorem. Facer \t",
}
# Function calls as keys
tasks = {
get_key_name(
foo,
bar,
baz,
): src,
loop.run_in_executor(): src,
loop.run_in_executor(xx_xxxxxxxxxxxxxxxxx_xxxxx_xxxxxxx_xxxxxxxxxxxxxx): src,
loop.run_in_executor(
xx_xxxxxxxxxxxxxxxxx_xxxxx_xxxxxxx_xxxxxxxxxxxxxx_xxxxx_xxxxx
): src,
loop.run_in_executor(): (
xx_xxxxxxxxxxxxxxxxx_xxxxx_xxxxxxx_xxxxxxxxxxxxxx_xxxxx_xxxxxxxxx_xxxxxxxxxxxx_xxxx
),
}
# Dictionary comprehensions
tasks = {
key_name: (
xx_xxxxxxxxxxxxxxxxx_xxxxx_xxxxxxx_xxxxxxxxxxxxxx_xxxxx_xxxxxxxxx_xxxxxxxxxxxx_xxxx
)
for src in sources
}
tasks = {key_name: foobar for src in sources}
tasks = {
get_key_name(
src,
): "foo"
for src in sources
}
tasks = {
get_key_name(
foo,
bar,
baz,
): src
for src in sources
}
tasks = {
get_key_name(): (
xx_xxxxxxxxxxxxxxxxx_xxxxx_xxxxxxx_xxxxxxxxxxxxxx_xxxxx_xxxxxxxxx_xxxxxxxxxxxx_xxxx
)
for src in sources
}
tasks = {get_key_name(): foobar for src in sources}
# Delimiters inside the value
def foo():
def bar():
x = {
common.models.DateTimeField: datetime(2020, 1, 31, tzinfo=utc) + timedelta(
days=i
),
}
x = {
common.models.DateTimeField: (
datetime(2020, 1, 31, tzinfo=utc) + timedelta(days=i)
),
}
x = {
"foobar": (123 + 456),
}
x = {
"foobar": (123) + 456,
}
my_dict = {
"a key in my dict": a_very_long_variable * and_a_very_long_function_call() / 100000.0
}
my_dict = {
"a key in my dict": a_very_long_variable * and_a_very_long_function_call() * and_another_long_func() / 100000.0
}
my_dict = {
"a key in my dict": MyClass.some_attribute.first_call().second_call().third_call(some_args="some value")
}
{
'xxxxxx':
"xxxxxx":
xxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxx(
xxxxxxxxxxxxxx={
'x':
"x":
xxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxx(
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=(
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
@ -29,8 +117,8 @@ my_dict = {
xxxxxxxxxxxxx=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx={
'x': x.xx,
'x': x.x,
"x": x.xx,
"x": x.x,
}))))
}),
}

View file

@ -1,3 +1,24 @@
x = {
"xx_xxxxx_xxxxxxxxxx_xxxxxxxxx_xx": (
"xx:xxxxxxxxxxxxxxxxx_xxxxx_xxxxxxx_xxxxxxxxxxx{xx}xxx_xxxxx_xxxxxxxxx_xxxxxxxxxxxx_xxxx"
)
}
x = {
"xx_xxxxx_xxxxxxxxxx_xxxxxxxxx_xx": (
"xx:xxxxxxxxxxxxxxxxx_xxxxx_xxxxxxx_xxxxxxxxxxx{xx}xxx_xxxxx_xxxxxxxxx_xxxxxxxxxxxx_xxxx"
),
}
x = {
"foo": bar,
"foo": bar,
"foo": (
xx_xxxxxxxxxxxxxxxxx_xxxxx_xxxxxxx_xxxxxxxxxxxxxx_xxxxx_xxxxxxxxx_xxxxxxxxxxxx_xxxx
),
}
x = {
"xx_xxxxx_xxxxxxxxxx_xxxxxxxxx_xx": "xx:xxxxxxxxxxxxxxxxx_xxxxx_xxxxxxx_xxxxxxxxxx"
}
my_dict = {
"something_something": (
r"Lorem ipsum dolor sit amet, an sed convenire eloquentiam \t"
@ -6,12 +27,80 @@ my_dict = {
),
}
# Function calls as keys
tasks = {
get_key_name(
foo,
bar,
baz,
): src,
loop.run_in_executor(): src,
loop.run_in_executor(xx_xxxxxxxxxxxxxxxxx_xxxxx_xxxxxxx_xxxxxxxxxxxxxx): src,
loop.run_in_executor(
xx_xxxxxxxxxxxxxxxxx_xxxxx_xxxxxxx_xxxxxxxxxxxxxx_xxxxx_xxxxx
): src,
loop.run_in_executor(): (
xx_xxxxxxxxxxxxxxxxx_xxxxx_xxxxxxx_xxxxxxxxxxxxxx_xxxxx_xxxxxxxxx_xxxxxxxxxxxx_xxxx
),
}
# Dictionary comprehensions
tasks = {
key_name: (
xx_xxxxxxxxxxxxxxxxx_xxxxx_xxxxxxx_xxxxxxxxxxxxxx_xxxxx_xxxxxxxxx_xxxxxxxxxxxx_xxxx
)
for src in sources
}
tasks = {key_name: foobar for src in sources}
tasks = {
get_key_name(
src,
): "foo"
for src in sources
}
tasks = {
get_key_name(
foo,
bar,
baz,
): src
for src in sources
}
tasks = {
get_key_name(): (
xx_xxxxxxxxxxxxxxxxx_xxxxx_xxxxxxx_xxxxxxxxxxxxxx_xxxxx_xxxxxxxxx_xxxxxxxxxxxx_xxxx
)
for src in sources
}
tasks = {get_key_name(): foobar for src in sources}
# Delimiters inside the value
def foo():
def bar():
x = {
common.models.DateTimeField: (
datetime(2020, 1, 31, tzinfo=utc) + timedelta(days=i)
),
}
x = {
common.models.DateTimeField: (
datetime(2020, 1, 31, tzinfo=utc) + timedelta(days=i)
),
}
x = {
"foobar": 123 + 456,
}
x = {
"foobar": (123) + 456,
}
my_dict = {
"a key in my dict": (
a_very_long_variable * and_a_very_long_function_call() / 100000.0
)
}
my_dict = {
"a key in my dict": (
a_very_long_variable
@ -20,7 +109,6 @@ my_dict = {
/ 100000.0
)
}
my_dict = {
"a key in my dict": (
MyClass.some_attribute.first_call()
@ -51,8 +139,8 @@ my_dict = {
class Random:
def func():
random_service.status.active_states.inactive = (
make_new_top_level_state_from_dict({
random_service.status.active_states.inactive = make_new_top_level_state_from_dict(
{
"topLevelBase": {
"secondaryBase": {
"timestamp": 1234,
@ -63,5 +151,5 @@ class Random:
),
}
},
})
}
)

View file

@ -278,7 +278,7 @@ string_with_escaped_nameescape = (
"........................................................................... \\N{LAO KO LA}"
)
msg = lambda x: f"this is a very very very long lambda value {x} that doesn't fit on a single line"
msg = lambda x: f"this is a very very very very long lambda value {x} that doesn't fit on a single line"
dict_with_lambda_values = {
"join": lambda j: (
@ -327,3 +327,17 @@ log.info(f'''Skipping: {"a" == 'b'} {desc["ms_name"]} {money=} {dte=} {pos_share
log.info(f'''Skipping: {'a' == "b"=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}''')
log.info(f"""Skipping: {'a' == 'b'} {desc['ms_name']} {money=} {dte=} {pos_share=} {desc['status']} {desc['exposure_max']}""")
x = {
"xx_xxxxx_xxxxxxxxxx_xxxxxxxxx_xx": (
"xx:xxxxxxxxxxxxxxxxx_xxxxx_xxxxxxx_xxxxxxxxxxx{xx}xxx_xxxxx_xxxxxxxxx_xxxxxxxxxxxx_xxxx"
)
}
x = {
"xx_xxxxx_xxxxxxxxxx_xxxxxxxxx_xx": "xx:xxxxxxxxxxxxxxxxx_xxxxx_xxxxxxx_xxxxxxxxxxx{xx}xxx_xxxxx_xxxxxxxxx_xxxxxxxxxxxx_xxxx",
}
x = {
"xx_xxxxx_xxxxxxxxxx_xxxxxxxxx_xx": (
"xx:xxxxxxxxxxxxxxxxx_xxxxx_xxxxxxx_xxxxxxxxxx"
)
}

View file

@ -508,11 +508,9 @@ string_with_escaped_nameescape = (
" \\N{LAO KO LA}"
)
msg = (
lambda x: (
f"this is a very very very long lambda value {x} that doesn't fit on a single"
" line"
)
msg = lambda x: (
f"this is a very very very very long lambda value {x} that doesn't fit on a"
" single line"
)
dict_with_lambda_values = {
@ -537,43 +535,43 @@ code = (
call(body="%s %s" % (",".join(items), suffix))
log.info(
"Skipping:"
f' {desc["db_id"]=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]=} {desc["exposure_max"]=}'
f'Skipping: {desc["db_id"]=} {desc["ms_name"]} {money=} {dte=} {pos_share=}'
f' {desc["status"]=} {desc["exposure_max"]=}'
)
log.info(
"Skipping:"
f" {desc['db_id']=} {desc['ms_name']} {money=} {dte=} {pos_share=} {desc['status']=} {desc['exposure_max']=}"
f"Skipping: {desc['db_id']=} {desc['ms_name']} {money=} {dte=} {pos_share=}"
f" {desc['status']=} {desc['exposure_max']=}"
)
log.info(
"Skipping:"
f" {desc['db_id']} {foo('bar',x=123)} {'foo' != 'bar'} {(x := 'abc=')} {pos_share=} {desc['status']} {desc['exposure_max']}"
f'Skipping: {desc["db_id"]} {foo("bar",x=123)} {"foo" != "bar"} {(x := "abc=")}'
f' {pos_share=} {desc["status"]} {desc["exposure_max"]}'
)
log.info(
"Skipping:"
f' {desc["db_id"]} {desc["ms_name"]} {money=} {(x := "abc=")=} {pos_share=} {desc["status"]} {desc["exposure_max"]}'
f'Skipping: {desc["db_id"]} {desc["ms_name"]} {money=} {(x := "abc=")=}'
f' {pos_share=} {desc["status"]} {desc["exposure_max"]}'
)
log.info(
"Skipping:"
f' {desc["db_id"]} {foo("bar",x=123)=} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}'
f'Skipping: {desc["db_id"]} {foo("bar",x=123)=} {money=} {dte=} {pos_share=}'
f' {desc["status"]} {desc["exposure_max"]}'
)
log.info(
"Skipping:"
f' {foo("asdf")=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}'
f'Skipping: {foo("asdf")=} {desc["ms_name"]} {money=} {dte=} {pos_share=}'
f' {desc["status"]} {desc["exposure_max"]}'
)
log.info(
"Skipping:"
f" {'a' == 'b' == 'c' == 'd'} {desc['ms_name']} {money=} {dte=} {pos_share=} {desc['status']} {desc['exposure_max']}"
f'Skipping: {"a" == "b" == "c" == "d"} {desc["ms_name"]} {money=} {dte=}'
f' {pos_share=} {desc["status"]} {desc["exposure_max"]}'
)
log.info(
"Skipping:"
f' {"a" == "b" == "c" == "d"=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}'
f'Skipping: {"a" == "b" == "c" == "d"=} {desc["ms_name"]} {money=} {dte=}'
f' {pos_share=} {desc["status"]} {desc["exposure_max"]}'
)
log.info(
@ -592,3 +590,17 @@ log.info(
log.info(
f"""Skipping: {'a' == 'b'} {desc['ms_name']} {money=} {dte=} {pos_share=} {desc['status']} {desc['exposure_max']}"""
)
x = {
"xx_xxxxx_xxxxxxxxxx_xxxxxxxxx_xx": (
"xx:xxxxxxxxxxxxxxxxx_xxxxx_xxxxxxx_xxxxxxxxxxx{xx}xxx_xxxxx_xxxxxxxxx_xxxxxxxxxxxx_xxxx"
)
}
x = {
"xx_xxxxx_xxxxxxxxxx_xxxxxxxxx_xx": (
"xx:xxxxxxxxxxxxxxxxx_xxxxx_xxxxxxx_xxxxxxxxxxx{xx}xxx_xxxxx_xxxxxxxxx_xxxxxxxxxxxx_xxxx"
),
}
x = {
"xx_xxxxx_xxxxxxxxxx_xxxxxxxxx_xx": "xx:xxxxxxxxxxxxxxxxx_xxxxx_xxxxxxx_xxxxxxxxxx"
}

View file

@ -551,6 +551,7 @@ a_dict = {
}
# Regression test for https://github.com/psf/black/issues/3506.
# Regressed again by https://github.com/psf/black/pull/4498
s = (
"With single quote: ' "
f" {my_dict['foo']}"

View file

@ -672,9 +672,15 @@ a_dict = {
}
# Regression test for https://github.com/psf/black/issues/3506.
s = f"With single quote: ' {my_dict['foo']} With double quote: \" {my_dict['bar']}"
# Regressed again by https://github.com/psf/black/pull/4498
s = (
"With single quote: ' "
f" {my_dict['foo']}"
' With double quote: " '
f' {my_dict["bar"]}'
)
s = (
"Lorem Ipsum is simply dummy text of the printing and typesetting"
f" industry:'{my_dict['foo']}'"
f' industry:\'{my_dict["foo"]}\''
)

View file

@ -180,3 +180,70 @@ test
assert some_var == expected_result, f"""
expected: {expected_result}
actual: {some_var}"""
def foo():
a = {
xxxx_xxxxxxx.xxxxxx_xxxxxxxxxxxx_xxxxxx_xx_xxx_xxxxxx: {
"xxxxx": """Sxxxxx xxxxxxxxxxxx xxx xxxxx (xxxxxx xxx xxxxxxx)""",
"xxxxxxxx": (
"""Sxxxxxxx xxxxxxxx, xxxxxxx xx xxxxxxxxx
xxxxxxxxxxxxx xxxxxxx xxxxxxxxx xxx-xxxxxxxxxx xxxxxx xx xxx-xxxxxx"""
),
"xxxxxxxx": """Sxxxxxxx xxxxxxxx, xxxxxxx xx xxxxxxxxx
xxxxxxxxxxxxx xxxxxxx xxxxxxxxx xxx-xxxxxxxxxx xxxxxx xx xxx-xxxxxx"""
},
}
xxxx_xxxxxxx.xxxxxx_xxxxxxxxxxxx_xxxxxx_xx_xxx_xxxxxx = {
"xxxxx": """Sxxxxx xxxxxxxxxxxx xxx xxxxx (xxxxxx xxx xxxxxxx)""",
"xxxxxxxx": (
"""Sxxxxxxx xxxxxxxx, xxxxxxx xx xxxxxxxxx
xxxxxxxxxxxxx xxxxxxx xxxxxxxxx xxx-xxxxxxxxxx xxxxxx xx xxx-xxxxxx"""
),
"xxxxx_xxxxxxxxxx_xxxxxxxxx_xx": (
"""
a
a
a
a
a"""
),
"xx_xxxxx_xxxxxxxxxx_xxxxxxxxx_xx": """
a
a
a
a
a""",
}
a = """
""" if """
""" == """
""" else """
"""
a = """
""" if b else """
"""
a = """
""" if """
""" == """
""" else b
a = b if """
""" == """
""" else """
"""
a = """
""" if b else c
a = c if b else """
"""
a = b if """
""" == """
""" else c

View file

@ -214,3 +214,106 @@ test
assert some_var == expected_result, f"""
expected: {expected_result}
actual: {some_var}"""
def foo():
a = {
xxxx_xxxxxxx.xxxxxx_xxxxxxxxxxxx_xxxxxx_xx_xxx_xxxxxx: {
"xxxxx": """Sxxxxx xxxxxxxxxxxx xxx xxxxx (xxxxxx xxx xxxxxxx)""",
"xxxxxxxx": (
"""Sxxxxxxx xxxxxxxx, xxxxxxx xx xxxxxxxxx
xxxxxxxxxxxxx xxxxxxx xxxxxxxxx xxx-xxxxxxxxxx xxxxxx xx xxx-xxxxxx"""
),
"xxxxxxxx": (
"""Sxxxxxxx xxxxxxxx, xxxxxxx xx xxxxxxxxx
xxxxxxxxxxxxx xxxxxxx xxxxxxxxx xxx-xxxxxxxxxx xxxxxx xx xxx-xxxxxx"""
),
},
}
xxxx_xxxxxxx.xxxxxx_xxxxxxxxxxxx_xxxxxx_xx_xxx_xxxxxx = {
"xxxxx": """Sxxxxx xxxxxxxxxxxx xxx xxxxx (xxxxxx xxx xxxxxxx)""",
"xxxxxxxx": (
"""Sxxxxxxx xxxxxxxx, xxxxxxx xx xxxxxxxxx
xxxxxxxxxxxxx xxxxxxx xxxxxxxxx xxx-xxxxxxxxxx xxxxxx xx xxx-xxxxxx"""
),
"xxxxx_xxxxxxxxxx_xxxxxxxxx_xx": (
"""
a
a
a
a
a"""
),
"xx_xxxxx_xxxxxxxxxx_xxxxxxxxx_xx": (
"""
a
a
a
a
a"""
),
}
a = (
"""
"""
if """
"""
== """
"""
else """
"""
)
a = (
"""
"""
if b
else """
"""
)
a = (
"""
"""
if """
"""
== """
"""
else b
)
a = (
b
if """
"""
== """
"""
else """
"""
)
a = (
"""
"""
if b
else c
)
a = (
c
if b
else """
"""
)
a = (
b
if """
"""
== """
"""
else c
)

View file

@ -0,0 +1,136 @@
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

View file

@ -0,0 +1,106 @@
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

View file

@ -0,0 +1 @@
{"preview": "enabled", "line_width": 79}

View file

@ -0,0 +1,69 @@
[a for graph_path_expression in refined_constraint.condition_as_predicate.variables]
[
a
for graph_path_expression in refined_constraint.condition_as_predicate.variables
]
[
a
for graph_path_expression
in refined_constraint.condition_as_predicate.variables
]
[
a
for graph_path_expression in (
refined_constraint.condition_as_predicate.variables
)
]
[
(foobar_very_long_key, foobar_very_long_value)
for foobar_very_long_key, foobar_very_long_value in foobar_very_long_dictionary.items()
]
# Don't split the `in` if it's not too long
lcomp3 = [
element.split("\n", 1)[0]
for element in collection.select_elements()
# right
if element is not None
]
# Don't remove parens around ternaries
expected = [i for i in (a if b else c)]
# Nested arrays
# First in will not be split because it would still be too long
[[
x
for x in bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
for y in xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
]]
# Multiple comprehensions, only split the second `in`
graph_path_expressions_in_local_constraint_refinements = [
graph_path_expression
for refined_constraint in self._local_constraint_refinements.values()
if refined_constraint is not None
for graph_path_expression in refined_constraint.condition_as_predicate.variables
]
# Dictionary comprehensions
dict_with_really_long_names = {
really_really_long_key_name: an_even_longer_really_really_long_key_value
for really_really_long_key_name, an_even_longer_really_really_long_key_value in really_really_really_long_dict_name.items()
}
{
key_with_super_really_long_name: key_with_super_really_long_name
for key_with_super_really_long_name in dictionary_with_super_really_long_name
}
{
key_with_super_really_long_name: key_with_super_really_long_name
for key_with_super_really_long_name
in dictionary_with_super_really_long_name
}
{
key_with_super_really_long_name: key_with_super_really_long_name
for key in (
dictionary
)
}

View file

@ -0,0 +1,88 @@
[
a
for graph_path_expression in (
refined_constraint.condition_as_predicate.variables
)
]
[
a
for graph_path_expression in (
refined_constraint.condition_as_predicate.variables
)
]
[
a
for graph_path_expression in (
refined_constraint.condition_as_predicate.variables
)
]
[
a
for graph_path_expression in (
refined_constraint.condition_as_predicate.variables
)
]
[
(foobar_very_long_key, foobar_very_long_value)
for foobar_very_long_key, foobar_very_long_value in (
foobar_very_long_dictionary.items()
)
]
# Don't split the `in` if it's not too long
lcomp3 = [
element.split("\n", 1)[0]
for element in collection.select_elements()
# right
if element is not None
]
# Don't remove parens around ternaries
expected = [i for i in (a if b else c)]
# Nested arrays
# First in will not be split because it would still be too long
[
[
x
for x in bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
for y in (
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
)
]
]
# Multiple comprehensions, only split the second `in`
graph_path_expressions_in_local_constraint_refinements = [
graph_path_expression
for refined_constraint in self._local_constraint_refinements.values()
if refined_constraint is not None
for graph_path_expression in (
refined_constraint.condition_as_predicate.variables
)
]
# Dictionary comprehensions
dict_with_really_long_names = {
really_really_long_key_name: an_even_longer_really_really_long_key_value
for really_really_long_key_name, an_even_longer_really_really_long_key_value in (
really_really_really_long_dict_name.items()
)
}
{
key_with_super_really_long_name: key_with_super_really_long_name
for key_with_super_really_long_name in (
dictionary_with_super_really_long_name
)
}
{
key_with_super_really_long_name: key_with_super_really_long_name
for key_with_super_really_long_name in (
dictionary_with_super_really_long_name
)
}
{
key_with_super_really_long_name: key_with_super_really_long_name
for key in dictionary
}

View file

@ -10,6 +10,7 @@ def g():
async def func():
await ...
if test:
out_batched = [
i

View file

@ -10,6 +10,7 @@ def g():
async def func():
await ...
if test:
out_batched = [
i

View file

@ -0,0 +1 @@
{"preview": "enabled", "target_version": "3.14"}

View file

@ -0,0 +1,123 @@
# SEE PEP 758 FOR MORE DETAILS
# remains unchanged
try:
pass
except:
pass
# remains unchanged
try:
pass
except ValueError:
pass
try:
pass
except* ValueError:
pass
# parenthesis are removed
try:
pass
except (ValueError):
pass
try:
pass
except* (ValueError):
pass
# parenthesis are removed
try:
pass
except (ValueError) as e:
pass
try:
pass
except* (ValueError) as e:
pass
# remains unchanged
try:
pass
except (ValueError,):
pass
try:
pass
except* (ValueError,):
pass
# remains unchanged
try:
pass
except (ValueError,) as e:
pass
try:
pass
except* (ValueError,) as e:
pass
# remains unchanged
try:
pass
except ValueError, TypeError, KeyboardInterrupt:
pass
try:
pass
except* ValueError, TypeError, KeyboardInterrupt:
pass
# parenthesis are removed
try:
pass
except (ValueError, TypeError, KeyboardInterrupt):
pass
try:
pass
except* (ValueError, TypeError, KeyboardInterrupt):
pass
# parenthesis are not removed
try:
pass
except (ValueError, TypeError, KeyboardInterrupt) as e:
pass
try:
pass
except* (ValueError, TypeError, KeyboardInterrupt) as e:
pass
# parenthesis are removed
try:
pass
except (ValueError if True else TypeError):
pass
try:
pass
except* (ValueError if True else TypeError):
pass
# inner except: parenthesis are removed
# outer except: parenthsis are not removed
try:
try:
pass
except (TypeError, KeyboardInterrupt):
pass
except (ValueError,):
pass
try:
try:
pass
except* (TypeError, KeyboardInterrupt):
pass
except* (ValueError,):
pass

View file

@ -0,0 +1,123 @@
# SEE PEP 758 FOR MORE DETAILS
# remains unchanged
try:
pass
except:
pass
# remains unchanged
try:
pass
except ValueError:
pass
try:
pass
except* ValueError:
pass
# parenthesis are removed
try:
pass
except ValueError:
pass
try:
pass
except* ValueError:
pass
# parenthesis are removed
try:
pass
except ValueError as e:
pass
try:
pass
except* ValueError as e:
pass
# remains unchanged
try:
pass
except (ValueError,):
pass
try:
pass
except* (ValueError,):
pass
# remains unchanged
try:
pass
except (ValueError,) as e:
pass
try:
pass
except* (ValueError,) as e:
pass
# remains unchanged
try:
pass
except ValueError, TypeError, KeyboardInterrupt:
pass
try:
pass
except* ValueError, TypeError, KeyboardInterrupt:
pass
# parenthesis are removed
try:
pass
except ValueError, TypeError, KeyboardInterrupt:
pass
try:
pass
except* ValueError, TypeError, KeyboardInterrupt:
pass
# parenthesis are not removed
try:
pass
except (ValueError, TypeError, KeyboardInterrupt) as e:
pass
try:
pass
except* (ValueError, TypeError, KeyboardInterrupt) as e:
pass
# parenthesis are removed
try:
pass
except ValueError if True else TypeError:
pass
try:
pass
except* ValueError if True else TypeError:
pass
# inner except: parenthesis are removed
# outer except: parenthsis are not removed
try:
try:
pass
except TypeError, KeyboardInterrupt:
pass
except (ValueError,):
pass
try:
try:
pass
except* TypeError, KeyboardInterrupt:
pass
except* (ValueError,):
pass

View file

@ -0,0 +1 @@
{"preview": "enabled", "target_version": "3.11"}

View file

@ -0,0 +1,111 @@
# SEE PEP 758 FOR MORE DETAILS
# remains unchanged
try:
pass
except:
pass
# remains unchanged
try:
pass
except ValueError:
pass
try:
pass
except* ValueError:
pass
# parenthesis are removed
try:
pass
except (ValueError):
pass
try:
pass
except* (ValueError):
pass
# parenthesis are removed
try:
pass
except (ValueError) as e:
pass
try:
pass
except* (ValueError) as e:
pass
# remains unchanged
try:
pass
except (ValueError,):
pass
try:
pass
except* (ValueError,):
pass
# remains unchanged
try:
pass
except (ValueError,) as e:
pass
try:
pass
except* (ValueError,) as e:
pass
# parenthesis are not removed
try:
pass
except (ValueError, TypeError, KeyboardInterrupt):
pass
try:
pass
except* (ValueError, TypeError, KeyboardInterrupt):
pass
# parenthesis are not removed
try:
pass
except (ValueError, TypeError, KeyboardInterrupt) as e:
pass
try:
pass
except* (ValueError, TypeError, KeyboardInterrupt) as e:
pass
# parenthesis are removed
try:
pass
except (ValueError if True else TypeError):
pass
try:
pass
except* (ValueError if True else TypeError):
pass
# parenthesis are not removed
try:
try:
pass
except (TypeError, KeyboardInterrupt):
pass
except (ValueError,):
pass
try:
try:
pass
except* (TypeError, KeyboardInterrupt):
pass
except* (ValueError,):
pass

View file

@ -0,0 +1,111 @@
# SEE PEP 758 FOR MORE DETAILS
# remains unchanged
try:
pass
except:
pass
# remains unchanged
try:
pass
except ValueError:
pass
try:
pass
except* ValueError:
pass
# parenthesis are removed
try:
pass
except ValueError:
pass
try:
pass
except* ValueError:
pass
# parenthesis are removed
try:
pass
except ValueError as e:
pass
try:
pass
except* ValueError as e:
pass
# remains unchanged
try:
pass
except (ValueError,):
pass
try:
pass
except* (ValueError,):
pass
# remains unchanged
try:
pass
except (ValueError,) as e:
pass
try:
pass
except* (ValueError,) as e:
pass
# parenthesis are not removed
try:
pass
except (ValueError, TypeError, KeyboardInterrupt):
pass
try:
pass
except* (ValueError, TypeError, KeyboardInterrupt):
pass
# parenthesis are not removed
try:
pass
except (ValueError, TypeError, KeyboardInterrupt) as e:
pass
try:
pass
except* (ValueError, TypeError, KeyboardInterrupt) as e:
pass
# parenthesis are removed
try:
pass
except ValueError if True else TypeError:
pass
try:
pass
except* ValueError if True else TypeError:
pass
# parenthesis are not removed
try:
try:
pass
except (TypeError, KeyboardInterrupt):
pass
except (ValueError,):
pass
try:
try:
pass
except* (TypeError, KeyboardInterrupt):
pass
except* (ValueError,):
pass

View file

@ -0,0 +1,80 @@
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

View file

@ -0,0 +1,74 @@
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

View file

@ -1 +1 @@
{"preview": "enabled", "line_width": 79, "target_version": "3.10"}
{"line_width": 79, "target_version": "3.10"}

View file

@ -52,3 +52,16 @@ with ((((open("bla.txt")))) as f):
with ((((CtxManager1()))) as example1, (((CtxManager2()))) as example2):
...
# regression tests for #3678
with (a, *b):
pass
with (a, (b, *c)):
pass
with (a for b in c):
pass
with (a, (b for c in d)):
pass

View file

@ -61,3 +61,16 @@ with open("bla.txt") as f:
with CtxManager1() as example1, CtxManager2() as example2:
...
# regression tests for #3678
with (a, *b):
pass
with a, (b, *c):
pass
with (a for b in c):
pass
with a, (b for c in d):
pass

View file

@ -0,0 +1 @@
{"target_version": "3.12", "magic_trailing_comma": "ignore"}

View file

@ -0,0 +1,97 @@
def plain[T, B](a: T, b: T) -> T:
return a
def arg_magic[T, B](a: T, b: T,) -> T:
return a
def type_param_magic[T, B,](a: T, b: T) -> T:
return a
def both_magic[T, B,](a: T, b: T,) -> T:
return a
def plain_multiline[
T,
B
](
a: T,
b: T
) -> T:
return a
def arg_magic_multiline[
T,
B
](
a: T,
b: T,
) -> T:
return a
def type_param_magic_multiline[
T,
B,
](
a: T,
b: T
) -> T:
return a
def both_magic_multiline[
T,
B,
](
a: T,
b: T,
) -> T:
return a
def plain_mixed1[
T,
B
](a: T, b: T) -> T:
return a
def plain_mixed2[T, B](
a: T,
b: T
) -> T:
return a
def arg_magic_mixed1[
T,
B
](a: T, b: T,) -> T:
return a
def arg_magic_mixed2[T, B](
a: T,
b: T,
) -> T:
return a
def type_param_magic_mixed1[
T,
B,
](a: T, b: T) -> T:
return a
def type_param_magic_mixed2[T, B,](
a: T,
b: T
) -> T:
return a
def both_magic_mixed1[
T,
B,
](a: T, b: T,) -> T:
return a
def both_magic_mixed2[T, B,](
a: T,
b: T,
) -> T:
return a

View file

@ -0,0 +1,62 @@
def plain[T, B](a: T, b: T) -> T:
return a
def arg_magic[T, B](a: T, b: T) -> T:
return a
def type_param_magic[T, B](a: T, b: T) -> T:
return a
def both_magic[T, B](a: T, b: T) -> T:
return a
def plain_multiline[T, B](a: T, b: T) -> T:
return a
def arg_magic_multiline[T, B](a: T, b: T) -> T:
return a
def type_param_magic_multiline[T, B](a: T, b: T) -> T:
return a
def both_magic_multiline[T, B](a: T, b: T) -> T:
return a
def plain_mixed1[T, B](a: T, b: T) -> T:
return a
def plain_mixed2[T, B](a: T, b: T) -> T:
return a
def arg_magic_mixed1[T, B](a: T, b: T) -> T:
return a
def arg_magic_mixed2[T, B](a: T, b: T) -> T:
return a
def type_param_magic_mixed1[T, B](a: T, b: T) -> T:
return a
def type_param_magic_mixed2[T, B](a: T, b: T) -> T:
return a
def both_magic_mixed1[T, B](a: T, b: T) -> T:
return a
def both_magic_mixed2[T, B](a: T, b: T) -> T:
return a

View file

@ -0,0 +1 @@
{"target_version": "3.12"}

View file

@ -0,0 +1,4 @@
# this is invalid in versions below py312
class ClassA[T: str]:
def method1(self) -> T:
...

View file

@ -0,0 +1,3 @@
# this is invalid in versions below py312
class ClassA[T: str]:
def method1(self) -> T: ...

View file

@ -0,0 +1,30 @@
# don't remove the brackets here, it changes the meaning of the code.
# even though the code will always trigger a runtime error
with (name_5, name_4), name_5:
pass
with c, (a, b):
pass
with c, (a, b), d:
pass
with c, (a, b, e, f, g), d:
pass
def test_tuple_as_contextmanager():
from contextlib import nullcontext
try:
with (nullcontext(), nullcontext()), nullcontext():
pass
except TypeError:
# test passed
pass
else:
# this should be a type error
assert False

View file

@ -0,0 +1,30 @@
# don't remove the brackets here, it changes the meaning of the code.
# even though the code will always trigger a runtime error
with (name_5, name_4), name_5:
pass
with c, (a, b):
pass
with c, (a, b), d:
pass
with c, (a, b, e, f, g), d:
pass
def test_tuple_as_contextmanager():
from contextlib import nullcontext
try:
with (nullcontext(), nullcontext()), nullcontext():
pass
except TypeError:
# test passed
pass
else:
# this should be a type error
assert False

View file

@ -0,0 +1 @@
{"preview": "enabled", "target_version": "3.12"}

View file

@ -0,0 +1,13 @@
def f1[T: (int, str)](a,): pass
def f2[T: (int, str)](a: int, b,): pass
def g1[T: (int,)](a,): pass
def g2[T: (int, str, bytes)](a,): pass
def g3[T: ((int, str), (bytes,))](a,): pass
def g4[T: (int, (str, bytes))](a,): pass
def g5[T: ((int,),)](a: int, b,): pass

View file

@ -0,0 +1,42 @@
def f1[T: (int, str)](
a,
):
pass
def f2[T: (int, str)](
a: int,
b,
):
pass
def g1[T: (int,)](
a,
):
pass
def g2[T: (int, str, bytes)](
a,
):
pass
def g3[T: ((int, str), (bytes,))](
a,
):
pass
def g4[T: (int, (str, bytes))](
a,
):
pass
def g5[T: ((int,),)](
a: int,
b,
):
pass

View file

@ -17,3 +17,5 @@ def trailing_comma1[T=int,](a: str):
def trailing_comma2[T=int](a: str,):
pass
def weird_syntax[T=lambda: 42, **P=lambda: 43, *Ts=lambda: 44](): pass

View file

@ -13,25 +13,31 @@ type something_that_is_long[
] = something_that_is_long
def simple[
T = something_that_is_long
](short1: int, short2: str, short3: bytes) -> float:
def simple[T = something_that_is_long](
short1: int, short2: str, short3: bytes
) -> float:
pass
def longer[
something_that_is_long = something_that_is_long
](something_that_is_long: something_that_is_long) -> something_that_is_long:
def longer[something_that_is_long = something_that_is_long](
something_that_is_long: something_that_is_long,
) -> something_that_is_long:
pass
def trailing_comma1[
T = int,
](a: str):
](
a: str,
):
pass
def trailing_comma2[
T = int
](a: str,):
def trailing_comma2[T = int](
a: str,
):
pass
def weird_syntax[T = lambda: 42, **P = lambda: 43, *Ts = lambda: 44]():
pass

View file

@ -11,3 +11,7 @@ def even_longer[WhatIsTheLongestTypeVarNameYouCanThinkOfEnoughToMakeBlackSplitTh
def it_gets_worse[WhatIsTheLongestTypeVarNameYouCanThinkOfEnoughToMakeBlackSplitThisLine, ItCouldBeGenericOverMultipleTypeVars](): pass
def magic[Trailing, Comma,](): pass
def weird_syntax[T: lambda: 42, U: a or b](): pass
def name_3[name_0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa if aaaaaaaaaaa else name_3](): pass

View file

@ -38,3 +38,13 @@ def magic[
Comma,
]():
pass
def weird_syntax[T: lambda: 42, U: a or b]():
pass
def name_3[
name_0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa if aaaaaaaaaaa else name_3
]():
pass

View file

@ -1,4 +1,4 @@
# This is testing an issue that is specific to the preview style
# This is testing an issue that is specific to the preview style (wrap_long_dict_values_in_parens)
{
"is_update": (up := commit.hash in update_hashes)
}

View file

@ -1,2 +1,2 @@
# This is testing an issue that is specific to the preview style
# This is testing an issue that is specific to the preview style (wrap_long_dict_values_in_parens)
{"is_update": (up := commit.hash in update_hashes)}

View file

@ -113,10 +113,10 @@ IGNORE_LIST = [
# Specs for which to override the formatter options
OPTIONS_OVERRIDES = {
"context_managers_38.py": {
"target_version": "py38"
"target_version": "3.8"
},
"context_managers_autodetect_38.py" : {
"target_version": "py38"
"target_version": "3.8"
}
}

Some files were not shown because too many files have changed in this diff Show more