|
1 | 1 | # The (future of the) Black code style
|
2 | 2 |
|
3 |
| -```{warning} |
4 |
| -Changes to this document often aren't tied and don't relate to releases of |
5 |
| -_Black_. It's recommended that you read the latest version available. |
6 |
| -``` |
7 |
| - |
8 |
| -## Using backslashes for with statements |
9 |
| - |
10 |
| -[Backslashes are bad and should be never be used](labels/why-no-backslashes) however |
11 |
| -there is one exception: `with` statements using multiple context managers. Before Python |
12 |
| -3.9 Python's grammar does not allow organizing parentheses around the series of context |
13 |
| -managers. |
14 |
| - |
15 |
| -We don't want formatting like: |
16 |
| - |
17 |
| -```py3 |
18 |
| -with make_context_manager1() as cm1, make_context_manager2() as cm2, make_context_manager3() as cm3, make_context_manager4() as cm4: |
19 |
| - ... # nothing to split on - line too long |
20 |
| -``` |
21 |
| - |
22 |
| -So _Black_ will, when we implement this, format it like this: |
23 |
| - |
24 |
| -```py3 |
25 |
| -with \ |
26 |
| - make_context_manager1() as cm1, \ |
27 |
| - make_context_manager2() as cm2, \ |
28 |
| - make_context_manager3() as cm3, \ |
29 |
| - make_context_manager4() as cm4 \ |
30 |
| -: |
31 |
| - ... # backslashes and an ugly stranded colon |
32 |
| -``` |
33 |
| - |
34 |
| -Although when the target version is Python 3.9 or higher, _Black_ uses parentheses |
35 |
| -instead in `--preview` mode (see below) since they're allowed in Python 3.9 and higher. |
36 |
| - |
37 |
| -An alternative to consider if the backslashes in the above formatting are undesirable is |
38 |
| -to use {external:py:obj}`contextlib.ExitStack` to combine context managers in the |
39 |
| -following way: |
40 |
| - |
41 |
| -```python |
42 |
| -with contextlib.ExitStack() as exit_stack: |
43 |
| - cm1 = exit_stack.enter_context(make_context_manager1()) |
44 |
| - cm2 = exit_stack.enter_context(make_context_manager2()) |
45 |
| - cm3 = exit_stack.enter_context(make_context_manager3()) |
46 |
| - cm4 = exit_stack.enter_context(make_context_manager4()) |
47 |
| - ... |
48 |
| -``` |
49 |
| - |
50 |
| -(labels/preview-style)= |
51 |
| - |
52 | 3 | ## Preview style
|
53 | 4 |
|
54 | 5 | Experimental, potentially disruptive style changes are gathered under the `--preview`
|
55 | 6 | CLI flag. At the end of each year, these changes may be adopted into the default style,
|
56 | 7 | as described in [The Black Code Style](index.md). Because the functionality is
|
57 | 8 | experimental, feedback and issue reports are highly encouraged!
|
58 | 9 |
|
59 |
| -### Improved string processing |
60 |
| - |
61 |
| -_Black_ will split long string literals and merge short ones. Parentheses are used where |
62 |
| -appropriate. When split, parts of f-strings that don't need formatting are converted to |
63 |
| -plain strings. User-made splits are respected when they do not exceed the line length |
64 |
| -limit. Line continuation backslashes are converted into parenthesized strings. |
65 |
| -Unnecessary parentheses are stripped. The stability and status of this feature is |
66 |
| -tracked in [this issue](https://github.com/psf/black/issues/2188). |
67 |
| - |
68 |
| -### Improved line breaks |
69 |
| - |
70 |
| -For assignment expressions, _Black_ now prefers to split and wrap the right side of the |
71 |
| -assignment instead of left side. For example: |
72 |
| - |
73 |
| -```python |
74 |
| -some_dict[ |
75 |
| - "with_a_long_key" |
76 |
| -] = some_looooooooong_module.some_looooooooooooooong_function_name( |
77 |
| - first_argument, second_argument, third_argument |
78 |
| -) |
79 |
| -``` |
80 |
| - |
81 |
| -will be changed to: |
| 10 | +In the past, the preview style included some features with known bugs, so that we were |
| 11 | +unable to move these features to the stable style. Therefore, such features are now |
| 12 | +moved to the `--unstable` style. All features in the `--preview` style are expected to |
| 13 | +make it to next year's stable style; features in the `--unstable` style will be |
| 14 | +stabilized only if issues with them are fixed. If bugs are discovered in a `--preview` |
| 15 | +feature, it is demoted to the `--unstable` style. To avoid thrash when a feature is |
| 16 | +demoted from the `--preview` to the `--unstable` style, users can use the |
| 17 | +`--enable-unstable-feature` flag to enable specific unstable features. |
82 | 18 |
|
83 |
| -```python |
84 |
| -some_dict["with_a_long_key"] = ( |
85 |
| - some_looooooooong_module.some_looooooooooooooong_function_name( |
86 |
| - first_argument, second_argument, third_argument |
87 |
| - ) |
88 |
| -) |
89 |
| -``` |
| 19 | +Currently, the following features are included in the preview style: |
90 | 20 |
|
91 |
| -### Improved parentheses management |
| 21 | +- `hex_codes_in_unicode_sequences`: normalize casing of Unicode escape characters in |
| 22 | + strings |
| 23 | +- `unify_docstring_detection`: fix inconsistencies in whether certain strings are |
| 24 | + detected as docstrings |
| 25 | +- `hug_parens_with_braces_and_square_brackets`: more compact formatting of nested |
| 26 | + brackets ([see below](labels/hug-parens)) |
| 27 | +- `no_normalize_fmt_skip_whitespace`: whitespace before `# fmt: skip` comments is no |
| 28 | + longer normalized |
92 | 29 |
|
93 |
| -For dict literals with long values, they are now wrapped in parentheses. Unnecessary |
94 |
| -parentheses are now removed. For example: |
| 30 | +(labels/unstable-features)= |
95 | 31 |
|
96 |
| -```python |
97 |
| -my_dict = { |
98 |
| - "a key in my dict": a_very_long_variable |
99 |
| - * and_a_very_long_function_call() |
100 |
| - / 100000.0, |
101 |
| - "another key": (short_value), |
102 |
| -} |
103 |
| -``` |
| 32 | +The unstable style additionally includes the following features: |
104 | 33 |
|
105 |
| -will be changed to: |
| 34 | +- `string_processing`: split long string literals and related changes |
| 35 | + ([see below](labels/string-processing)) |
| 36 | +- `wrap_long_dict_values_in_parens`: add parentheses to long values in dictionaries |
| 37 | + ([see below](labels/wrap-long-dict-values)) |
| 38 | +- `multiline_string_handling`: more compact formatting of expressions involving |
| 39 | + multiline strings ([see below](labels/multiline-string-handling)) |
106 | 40 |
|
107 |
| -```python |
108 |
| -my_dict = { |
109 |
| - "a key in my dict": ( |
110 |
| - a_very_long_variable * and_a_very_long_function_call() / 100000.0 |
111 |
| - ), |
112 |
| - "another key": short_value, |
113 |
| -} |
114 |
| -``` |
| 41 | +(labels/hug-parens)= |
115 | 42 |
|
116 | 43 | ### Improved multiline dictionary and list indentation for sole function parameter
|
117 | 44 |
|
@@ -185,6 +112,46 @@ foo(
|
185 | 112 | )
|
186 | 113 | ```
|
187 | 114 |
|
| 115 | +(labels/string-processing)= |
| 116 | + |
| 117 | +### Improved string processing |
| 118 | + |
| 119 | +_Black_ will split long string literals and merge short ones. Parentheses are used where |
| 120 | +appropriate. When split, parts of f-strings that don't need formatting are converted to |
| 121 | +plain strings. User-made splits are respected when they do not exceed the line length |
| 122 | +limit. Line continuation backslashes are converted into parenthesized strings. |
| 123 | +Unnecessary parentheses are stripped. The stability and status of this feature is |
| 124 | +tracked in [this issue](https://github.com/psf/black/issues/2188). |
| 125 | + |
| 126 | +(labels/wrap-long-dict-values)= |
| 127 | + |
| 128 | +### Improved parentheses management in dicts |
| 129 | + |
| 130 | +For dict literals with long values, they are now wrapped in parentheses. Unnecessary |
| 131 | +parentheses are now removed. For example: |
| 132 | + |
| 133 | +```python |
| 134 | +my_dict = { |
| 135 | + "a key in my dict": a_very_long_variable |
| 136 | + * and_a_very_long_function_call() |
| 137 | + / 100000.0, |
| 138 | + "another key": (short_value), |
| 139 | +} |
| 140 | +``` |
| 141 | + |
| 142 | +will be changed to: |
| 143 | + |
| 144 | +```python |
| 145 | +my_dict = { |
| 146 | + "a key in my dict": ( |
| 147 | + a_very_long_variable * and_a_very_long_function_call() / 100000.0 |
| 148 | + ), |
| 149 | + "another key": short_value, |
| 150 | +} |
| 151 | +``` |
| 152 | + |
| 153 | +(labels/multiline-string-handling)= |
| 154 | + |
188 | 155 | ### Improved multiline string handling
|
189 | 156 |
|
190 | 157 | _Black_ is smarter when formatting multiline strings, especially in function arguments,
|
@@ -297,13 +264,51 @@ s = ( # Top comment
|
297 | 264 | )
|
298 | 265 | ```
|
299 | 266 |
|
300 |
| -======= |
| 267 | +## Potential future changes |
| 268 | + |
| 269 | +This section lists changes that we may want to make in the future, but that aren't |
| 270 | +implemented yet. |
| 271 | + |
| 272 | +### Using backslashes for with statements |
| 273 | + |
| 274 | +[Backslashes are bad and should be never be used](labels/why-no-backslashes) however |
| 275 | +there is one exception: `with` statements using multiple context managers. Before Python |
| 276 | +3.9 Python's grammar does not allow organizing parentheses around the series of context |
| 277 | +managers. |
| 278 | + |
| 279 | +We don't want formatting like: |
| 280 | + |
| 281 | +```py3 |
| 282 | +with make_context_manager1() as cm1, make_context_manager2() as cm2, make_context_manager3() as cm3, make_context_manager4() as cm4: |
| 283 | + ... # nothing to split on - line too long |
| 284 | +``` |
| 285 | + |
| 286 | +So _Black_ will, when we implement this, format it like this: |
| 287 | + |
| 288 | +```py3 |
| 289 | +with \ |
| 290 | + make_context_manager1() as cm1, \ |
| 291 | + make_context_manager2() as cm2, \ |
| 292 | + make_context_manager3() as cm3, \ |
| 293 | + make_context_manager4() as cm4 \ |
| 294 | +: |
| 295 | + ... # backslashes and an ugly stranded colon |
| 296 | +``` |
| 297 | + |
| 298 | +Although when the target version is Python 3.9 or higher, _Black_ uses parentheses |
| 299 | +instead in `--preview` mode (see below) since they're allowed in Python 3.9 and higher. |
301 | 300 |
|
302 |
| -### Form feed characters |
| 301 | +An alternative to consider if the backslashes in the above formatting are undesirable is |
| 302 | +to use {external:py:obj}`contextlib.ExitStack` to combine context managers in the |
| 303 | +following way: |
303 | 304 |
|
304 |
| -_Black_ will now retain form feed characters on otherwise empty lines at the module |
305 |
| -level. Only one form feed is retained for a group of consecutive empty lines. Where |
306 |
| -there are two empty lines in a row, the form feed will be placed on the second line. |
| 305 | +```python |
| 306 | +with contextlib.ExitStack() as exit_stack: |
| 307 | + cm1 = exit_stack.enter_context(make_context_manager1()) |
| 308 | + cm2 = exit_stack.enter_context(make_context_manager2()) |
| 309 | + cm3 = exit_stack.enter_context(make_context_manager3()) |
| 310 | + cm4 = exit_stack.enter_context(make_context_manager4()) |
| 311 | + ... |
| 312 | +``` |
307 | 313 |
|
308 |
| -_Black_ already retained form feed literals inside a comment or inside a string. This |
309 |
| -remains the case. |
| 314 | +(labels/preview-style)= |
0 commit comments