Discover whether a file is Python 3.6+ also by stars in calls
Fixes a pathological situation where if a function signature used a trailing comma but was later reformatted to a single line (with the trailing comma removed), Black would change its mind whether a file is Python 3.6-compatible between runs.
This commit is contained in:
parent
e196180a0d
commit
1747c388bb
@ -549,6 +549,11 @@ More details can be found in [CONTRIBUTING](CONTRIBUTING.md).
|
||||
|
||||
* fixed not splitting long from-imports with only a single name
|
||||
|
||||
* fixed Python 3.6+ file discovery by also looking at function calls with
|
||||
unpacking. This fixed non-deterministic formatting if trailing commas
|
||||
where used both in function signatures with stars and function calls
|
||||
with stars but the former would be reformatted to a single line.
|
||||
|
||||
|
||||
### 18.4a4
|
||||
|
||||
|
9
black.py
9
black.py
@ -2337,7 +2337,7 @@ def is_python36(node: Node) -> bool:
|
||||
|
||||
Currently looking for:
|
||||
- f-strings; and
|
||||
- trailing commas after * or ** in function signatures.
|
||||
- trailing commas after * or ** in function signatures and calls.
|
||||
"""
|
||||
for n in node.pre_order():
|
||||
if n.type == token.STRING:
|
||||
@ -2346,7 +2346,7 @@ def is_python36(node: Node) -> bool:
|
||||
return True
|
||||
|
||||
elif (
|
||||
n.type == syms.typedargslist
|
||||
n.type in {syms.typedargslist, syms.arglist}
|
||||
and n.children
|
||||
and n.children[-1].type == token.COMMA
|
||||
):
|
||||
@ -2354,6 +2354,11 @@ def is_python36(node: Node) -> bool:
|
||||
if ch.type in STARS:
|
||||
return True
|
||||
|
||||
if ch.type == syms.argument:
|
||||
for argch in ch.children:
|
||||
if argch.type in STARS:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
|
@ -81,6 +81,15 @@ def trailing_comma():
|
||||
C: 0.1 * (10.0 / 12),
|
||||
D: 0.1 * (10.0 / 12),
|
||||
}
|
||||
def f(
|
||||
a,
|
||||
**kwargs,
|
||||
) -> A:
|
||||
return A(
|
||||
very_long_argument_name1=very_long_value_for_the_argument,
|
||||
very_long_argument_name2=very_long_value_for_the_argument,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
# output
|
||||
|
||||
@ -212,3 +221,11 @@ def trailing_comma():
|
||||
C: 0.1 * (10.0 / 12),
|
||||
D: 0.1 * (10.0 / 12),
|
||||
}
|
||||
|
||||
|
||||
def f(a, **kwargs) -> A:
|
||||
return A(
|
||||
very_long_argument_name1=very_long_value_for_the_argument,
|
||||
very_long_argument_name2=very_long_value_for_the_argument,
|
||||
**kwargs,
|
||||
)
|
||||
|
18
tests/function2.py
Normal file
18
tests/function2.py
Normal file
@ -0,0 +1,18 @@
|
||||
def f(
|
||||
a,
|
||||
**kwargs,
|
||||
) -> A:
|
||||
return A(
|
||||
very_long_argument_name1=very_long_value_for_the_argument,
|
||||
very_long_argument_name2=very_long_value_for_the_argument,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
# output
|
||||
|
||||
def f(a, **kwargs) -> A:
|
||||
return A(
|
||||
very_long_argument_name1=very_long_value_for_the_argument,
|
||||
very_long_argument_name2=very_long_value_for_the_argument,
|
||||
**kwargs,
|
||||
)
|
@ -167,6 +167,14 @@ def test_function(self) -> None:
|
||||
black.assert_equivalent(source, actual)
|
||||
black.assert_stable(source, actual, line_length=ll)
|
||||
|
||||
@patch("black.dump_to_file", dump_to_stderr)
|
||||
def test_function2(self) -> None:
|
||||
source, expected = read_data("function2")
|
||||
actual = fs(source)
|
||||
self.assertFormatEqual(expected, actual)
|
||||
black.assert_equivalent(source, actual)
|
||||
black.assert_stable(source, actual, line_length=ll)
|
||||
|
||||
@patch("black.dump_to_file", dump_to_stderr)
|
||||
def test_expression(self) -> None:
|
||||
source, expected = read_data("expression")
|
||||
|
Loading…
Reference in New Issue
Block a user