Skip to content

Commit ede090e

Browse files
committed
Update Black deviations to reflect 2025 style changes (#15127)
1 parent 3e69e03 commit ede090e

File tree

1 file changed

+176
-12
lines changed

1 file changed

+176
-12
lines changed

docs/formatter/black.md

Lines changed: 176 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,8 @@ c = "\U0001f977"
215215
d = "\N{CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I}"
216216
```
217217

218+
Ruff's formatting matches Black's preview formatting, and we expect it to be part of [Black's 2025 style guide](https://github.com/psf/black/issues/4522).
219+
218220
### Module docstrings
219221

220222
Ruff formats module docstrings similar to class or function docstrings, whereas Black does not.
@@ -234,32 +236,133 @@ Ruff formats module docstrings similar to class or function docstrings, whereas
234236
"""Module docstring"""
235237

236238
```
239+
Ruff's formatting matches Black's preview formatting, and we expect it to be part of [Black's 2025 style guide](https://github.com/psf/black/issues/4522).
240+
241+
### F-strings
242+
243+
Ruff formats expression parts in f-strings whereas Black does not:
244+
245+
```python
246+
# Input
247+
f'test{inner + "nested_string"} including math {5 ** 3 + 10}'
248+
249+
# Black
250+
f'test{inner + "nested_string"} including math {5 ** 3 + 10}'
237251

252+
# Ruff
253+
f"test{inner + 'nested_string'} including math {5**3 + 10}"
254+
```
238255

239-
### Walruses in slice expressions
256+
### Implicit concatenated strings
240257

241-
Black avoids inserting space around `:=` operators within slices. For example, the following adheres
242-
to Black stable style:
258+
Ruff merges implicitly concatenated strings if the entire string fits on a single line:
243259

244260
```python
245261
# Input
246-
x[y:=1]
262+
def test(max_history):
263+
raise argparse.ArgumentTypeError(
264+
f"The value of `--max-history {max_history}` " f"is not a positive integer."
265+
)
266+
267+
# Black
268+
def test(max_history):
269+
raise argparse.ArgumentTypeError(
270+
f"The value of `--max-history {max_history}` " f"is not a positive integer."
271+
)
272+
273+
# Ruff
274+
def test(max_history):
275+
raise argparse.ArgumentTypeError(
276+
f"The value of `--max-history {max_history}` is not a positive integer."
277+
)
278+
```
279+
280+
Black's unstable style applies the same formatting.
281+
282+
There are few rare cases where Ruff can't merge the implicitly concatenated strings automatically.
283+
In those cases, Ruff preserves if the implicit concatenated strings are formatted over multiple lines:
284+
285+
```python
286+
# Input
287+
a = (
288+
r"aaaaaaa"
289+
"bbbbbbbbbbbb"
290+
)
291+
292+
# Black
293+
a = r"aaaaaaa" "bbbbbbbbbbbb"
294+
295+
# Ruff
296+
a = (
297+
r"aaaaaaa"
298+
"bbbbbbbbbbbb"
299+
)
300+
```
301+
302+
This ensures compatibility with `ISC001` ([#8272](https://github.com/astral-sh/ruff/issues/8272)).
303+
304+
### `assert` statements
305+
306+
Unlike Black, Ruff prefers breaking the message over breaking the assertion, similar to how both Ruff and Black prefer breaking the assignment value over breaking the assignment target:
307+
308+
```python
309+
# Input
310+
assert (
311+
len(policy_types) >= priority + num_duplicates
312+
), f"This tests needs at least {priority+num_duplicates} many types."
313+
247314

248315
# Black
249-
x[y:=1]
316+
assert (
317+
len(policy_types) >= priority + num_duplicates
318+
), f"This tests needs at least {priority+num_duplicates} many types."
319+
320+
# Ruff
321+
assert len(policy_types) >= priority + num_duplicates, (
322+
f"This tests needs at least {priority + num_duplicates} many types."
323+
)
250324
```
251325

252-
Ruff will instead add space around the `:=` operator:
326+
### Parentheses around `if`-guards in `match` statements
327+
Ruff automatically parenthesizes overlong `if` guards and it also removes parentheses if they're no longer required.
253328

254329
```python
255330
# Input
256-
x[y:=1]
331+
match some_variable:
332+
case "short-guard" if (
333+
other_condition
334+
):
335+
pass
257336

337+
case "long-guard" if other_condition or some_long_call_expression(with_may, arguments) or last_condition:
338+
pass
339+
340+
341+
# Black
342+
match some_variable:
343+
case "short-guard" if (other_condition):
344+
pass
345+
346+
case "long-guard" if other_condition or some_long_call_expression(
347+
with_may, arguments
348+
) or last_condition:
349+
pass
350+
351+
258352
# Ruff
259-
x[y := 1]
353+
match some_variable:
354+
case "short-guard" if other_condition:
355+
pass
356+
357+
case "long-guard" if (
358+
other_condition
359+
or some_long_call_expression(with_may, arguments)
360+
or last_condition
361+
):
362+
pass
260363
```
261364

262-
This will likely be incorporated into Black's preview style ([#3823](https://github.com/psf/black/pull/3823)).
365+
Ruff's formatting matches Black's preview formatting, and we expect it to be part of [Black's 2025 style guide](https://github.com/psf/black/issues/4522).
263366

264367
### `global` and `nonlocal` names are broken across multiple lines by continuations
265368

@@ -309,6 +412,8 @@ class IntFromGeom(GEOSFuncFactory):
309412
errcheck = staticmethod(check_minus_one)
310413
```
311414

415+
Ruff's formatting matches Black's preview formatting, and we expect it to be part of [Black's 2025 style guide](https://github.com/psf/black/issues/4522).
416+
312417
### Trailing own-line comments on imports are not moved to the next line
313418

314419
Black enforces a single empty line between an import and a trailing own-line comment. Ruff leaves
@@ -385,9 +490,7 @@ would instead format the above as:
385490

386491
```python
387492
print(
388-
"aaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaa".format(
389-
bbbbbbbbbbbbbbbbbb + bbbbbbbbbbbbbbbbbb
390-
)
493+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa".format(bbbbbbbbbbbbbbbbbb + bbbbbbbbbbbbbbbbbb)
391494
)
392495
```
393496

@@ -528,6 +631,8 @@ def func(
528631

529632
Ruff will instead insert a trailing comma in all such cases for consistency.
530633

634+
Ruff's formatting matches Black's preview formatting, and we expect it to be part of [Black's 2025 style guide](https://github.com/psf/black/issues/4522).
635+
531636
### Parentheses around call-chain assignment values are not preserved
532637

533638
Given:
@@ -651,6 +756,65 @@ assert AAAAAAAAAAAAAAAAAAAAAA.bbbbbb.fooo(
651756
) * foooooo * len(list(foo(bar(4, foo), foo)))
652757
```
653758

759+
### Single `with` item targeting Python 3.8 or older
760+
761+
Unlike Black, Ruff uses the same layout for `with` statements with a single context manager as it does for `while`, `if` and other compound statements:
762+
763+
```python
764+
# Input
765+
def run(data_path, model_uri):
766+
with pyspark.sql.SparkSession.builder.config(
767+
key="spark.python.worker.reuse", value=True
768+
).config(key="spark.ui.enabled", value=False).master(
769+
"local-cluster[2, 1, 1024]"
770+
).getOrCreate():
771+
# ignore spark log output
772+
spark.sparkContext.setLogLevel("OFF")
773+
print(score_model(spark, data_path, model_uri))
774+
775+
# Black
776+
def run(data_path, model_uri):
777+
with pyspark.sql.SparkSession.builder.config(
778+
key="spark.python.worker.reuse", value=True
779+
).config(key="spark.ui.enabled", value=False).master(
780+
"local-cluster[2, 1, 1024]"
781+
).getOrCreate():
782+
# ignore spark log output
783+
spark.sparkContext.setLogLevel("OFF")
784+
print(score_model(spark, data_path, model_uri))
785+
786+
# Ruff
787+
def run(data_path, model_uri):
788+
with (
789+
pyspark.sql.SparkSession.builder.config(
790+
key="spark.python.worker.reuse", value=True
791+
)
792+
.config(key="spark.ui.enabled", value=False)
793+
.master("local-cluster[2, 1, 1024]")
794+
.getOrCreate()
795+
):
796+
# ignore spark log output
797+
spark.sparkContext.setLogLevel("OFF")
798+
print(score_model(spark, data_path, model_uri))
799+
```
800+
801+
Ruff's formatting matches the formatting of other compound statements:
802+
803+
```python
804+
def test():
805+
if (
806+
pyspark.sql.SparkSession.builder.config(
807+
key="spark.python.worker.reuse", value=True
808+
)
809+
.config(key="spark.ui.enabled", value=False)
810+
.master("local-cluster[2, 1, 1024]")
811+
.getOrCreate()
812+
):
813+
# ignore spark log output
814+
spark.sparkContext.setLogLevel("OFF")
815+
print(score_model(spark, data_path, model_uri))
816+
```
817+
654818
### The last context manager in a `with` statement may be collapsed onto a single line
655819

656820
When using a `with` statement with multiple unparenthesized context managers, Ruff may collapse the

0 commit comments

Comments
 (0)