Skip to content

Commit 4f47cac

Browse files
Add --unstable flag (#4096)
1 parent bccec8a commit 4f47cac

23 files changed

+368
-252
lines changed

CHANGES.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ changes:
3434
- Fix incorrect formatting of certain async statements (#3609)
3535
- Allow combining `# fmt: skip` with other comments (#3959)
3636

37+
There are already a few improvements in the `--preview` style, which are slated for the
38+
2025 stable style. Try them out and
39+
[share your feedback](https://github.com/psf/black/issues). In the past, the preview
40+
style has included some features that we were not able to stabilize. This year, we're
41+
adding a separate `--unstable` style for features with known problems. Now, the
42+
`--preview` style only includes features that we actually expect to make it into next
43+
year's stable style.
44+
3745
### Stable style
3846

3947
<!-- Changes that affect Black's stable style -->
@@ -53,6 +61,12 @@ release:
5361

5462
<!-- Changes that affect Black's preview style -->
5563

64+
- Add `--unstable` style, covering preview features that have known problems that would
65+
block them from going into the stable style. Also add the `--enable-unstable-feature`
66+
flag; for example, use
67+
`--enable-unstable-feature hug_parens_with_braces_and_square_brackets` to apply this
68+
preview style throughout 2024, even if a later Black release downgrades the feature to
69+
unstable (#4096)
5670
- Format module docstrings the same as class and function docstrings (#4095)
5771
- Fix crash when using a walrus in a dictionary (#4155)
5872
- Fix unnecessary parentheses when wrapping long dicts (#4135)
@@ -66,6 +80,9 @@ release:
6680
- Fix symlink handling, properly catch and ignore symlinks that point outside of root
6781
(#4161)
6882
- Fix cache mtime logic that resulted in false positive cache hits (#4128)
83+
- Remove the long-deprecated `--experimental-string-processing` flag. This feature can
84+
currently be enabled with `--preview --enable-unstable-feature string_processing`.
85+
(#4096)
6986

7087
### Packaging
7188

docs/faq.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,10 @@ other tools, such as `# noqa`, may be moved by _Black_. See below for more detai
4141
Stable. _Black_ aims to enforce one style and one style only, with some room for
4242
pragmatism. See [The Black Code Style](the_black_code_style/index.md) for more details.
4343

44-
Starting in 2022, the formatting output will be stable for the releases made in the same
45-
year (other than unintentional bugs). It is possible to opt-in to the latest formatting
46-
styles, using the `--preview` flag.
44+
Starting in 2022, the formatting output is stable for the releases made in the same year
45+
(other than unintentional bugs). At the beginning of every year, the first release will
46+
make changes to the stable style. It is possible to opt in to the latest formatting
47+
styles using the `--preview` flag.
4748

4849
## Why is my file not formatted?
4950

docs/the_black_code_style/current_style.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,12 @@ file that are not enforced yet but might be in a future version of the formatter
449449
_Black_ will normalize line endings (`\n` or `\r\n`) based on the first line ending of
450450
the file.
451451

452+
### Form feed characters
453+
454+
_Black_ will retain form feed characters on otherwise empty lines at the module level.
455+
Only one form feed is retained for a group of consecutive empty lines. Where there are
456+
two empty lines in a row, the form feed is placed on the second line.
457+
452458
## Pragmatism
453459

454460
Early versions of _Black_ used to be absolutist in some respects. They took after its

docs/the_black_code_style/future_style.md

Lines changed: 111 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,117 +1,44 @@
11
# The (future of the) Black code style
22

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-
523
## Preview style
534

545
Experimental, potentially disruptive style changes are gathered under the `--preview`
556
CLI flag. At the end of each year, these changes may be adopted into the default style,
567
as described in [The Black Code Style](index.md). Because the functionality is
578
experimental, feedback and issue reports are highly encouraged!
589

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.
8218

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:
9020

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
9229

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)=
9531

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:
10433

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))
10640

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)=
11542

11643
### Improved multiline dictionary and list indentation for sole function parameter
11744

@@ -185,6 +112,46 @@ foo(
185112
)
186113
```
187114

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+
188155
### Improved multiline string handling
189156

190157
_Black_ is smarter when formatting multiline strings, especially in function arguments,
@@ -297,13 +264,51 @@ s = ( # Top comment
297264
)
298265
```
299266

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.
301300

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:
303304

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+
```
307313

308-
_Black_ already retained form feed literals inside a comment or inside a string. This
309-
remains the case.
314+
(labels/preview-style)=

docs/the_black_code_style/index.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,11 @@ _Black_:
4242
enabled by newer Python language syntax as well as due to improvements in the
4343
formatting logic.
4444

45-
- The `--preview` flag is exempt from this policy. There are no guarantees around the
46-
stability of the output with that flag passed into _Black_. This flag is intended for
47-
allowing experimentation with the proposed changes to the _Black_ code style.
45+
- The `--preview` and `--unstable` flags are exempt from this policy. There are no
46+
guarantees around the stability of the output with these flags passed into _Black_.
47+
They are intended for allowing experimentation with proposed changes to the _Black_
48+
code style. The `--preview` style at the end of a year should closely match the stable
49+
style for the next year, but we may always make changes.
4850

4951
Documentation for both the current and future styles can be found:
5052

docs/usage_and_configuration/black_as_a_server.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ The headers controlling how source code is formatted are:
6262
- `X-Preview`: corresponds to the `--preview` command line flag. If present and its
6363
value is not an empty string, experimental and potentially disruptive style changes
6464
will be used.
65+
- `X-Unstable`: corresponds to the `--unstable` command line flag. If present and its
66+
value is not an empty string, experimental style changes that are known to be buggy
67+
will be used.
68+
- `X-Enable-Unstable-Feature`: corresponds to the `--enable-unstable-feature` flag. The
69+
contents of the flag must be a comma-separated list of unstable features to be
70+
enabled. Example: `X-Enable-Unstable-Feature: feature1, feature2`.
6571
- `X-Fast-Or-Safe`: if set to `fast`, `blackd` will act as _Black_ does when passed the
6672
`--fast` command line flag.
6773
- `X-Python-Variant`: if set to `pyi`, `blackd` will act as _Black_ does when passed the

docs/usage_and_configuration/the_basics.md

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,34 @@ magic trailing comma is ignored.
144144

145145
#### `--preview`
146146

147-
Enable potentially disruptive style changes that may be added to Black's main
148-
functionality in the next major release. Read more about
149-
[our preview style](labels/preview-style).
147+
Enable potentially disruptive style changes that we expect to add to Black's main
148+
functionality in the next major release. Use this if you want a taste of what next
149+
year's style will look like.
150+
151+
Read more about [our preview style](labels/preview-style).
152+
153+
There is no guarantee on the code style produced by this flag across releases.
154+
155+
#### `--unstable`
156+
157+
Enable all style changes in `--preview`, plus additional changes that we would like to
158+
make eventually, but that have known issues that need to be fixed before they can move
159+
back to the `--preview` style. Use this if you want to experiment with these changes and
160+
help fix issues with them.
161+
162+
There is no guarantee on the code style produced by this flag across releases.
163+
164+
#### `--enable-unstable-feature`
165+
166+
Enable specific features from the `--unstable` style. See
167+
[the preview style documentation](labels/unstable-features) for the list of supported
168+
features. This flag can only be used when `--preview` is enabled. Users are encouraged
169+
to use this flag if they use `--preview` style and a feature that affects their code is
170+
moved from the `--preview` to the `--unstable` style, but they want to avoid the thrash
171+
from undoing this change.
172+
173+
There are no guarantees on the behavior of these features, or even their existence,
174+
across releases.
150175

151176
(labels/exit-code)=
152177

pyproject.toml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@ extend-exclude = '''
1616
| profiling
1717
)/
1818
'''
19-
# We use preview style for formatting Black itself. If you
20-
# want stable formatting across releases, you should keep
21-
# this off.
22-
preview = true
19+
# We use the unstable style for formatting Black itself. If you
20+
# want bug-free formatting, you should keep this off. If you want
21+
# stable formatting across releases, you should also keep `preview = true`
22+
# (which is implied by this flag) off.
23+
unstable = true
2324

2425
# Build system information and other project-specific configuration below.
2526
# NOTE: You don't need this in your own Black configuration.

0 commit comments

Comments
 (0)