From 9f1c9d37c0912b0e87b7a57188826f755a51bf1b Mon Sep 17 00:00:00 2001 From: cobalt <61329810+cobaltt7@users.noreply.github.com> Date: Sat, 20 Sep 2025 12:50:28 -0500 Subject: [PATCH 1/4] Move `multiline_string_handling` from unstable to preview --- src/black/mode.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/black/mode.py b/src/black/mode.py index 85a205949dc..f7489244472 100644 --- a/src/black/mode.py +++ b/src/black/mode.py @@ -241,8 +241,6 @@ class Preview(Enum): UNSTABLE_FEATURES: set[Preview] = { # Many issues, see summary in https://github.com/psf/black/issues/4042 Preview.string_processing, - # See issue #4159 - Preview.multiline_string_handling, # See issue #4036 (crash), #4098, #4099 (proposed tweaks) Preview.hug_parens_with_braces_and_square_brackets, } From a77d50fe77cb4344265090cd4d6e242c83c2b7f7 Mon Sep 17 00:00:00 2001 From: cobalt <61329810+cobaltt7@users.noreply.github.com> Date: Sat, 20 Sep 2025 14:03:32 -0500 Subject: [PATCH 2/4] Docs and tests Signed-off-by: cobalt <61329810+cobaltt7@users.noreply.github.com> --- CHANGES.md | 2 + docs/the_black_code_style/future_style.md | 205 ++++++------------ tests/data/cases/preview_multiline_strings.py | 29 +-- 3 files changed, 74 insertions(+), 162 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index e8d7c0b4e9a..ca9efa42923 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -14,6 +14,8 @@ +- Move `multiline_string_handling` from `--unstable` to `--preview` (#4760) + ### Configuration diff --git a/docs/the_black_code_style/future_style.md b/docs/the_black_code_style/future_style.md index 837aec457b0..bf88ec24dcd 100644 --- a/docs/the_black_code_style/future_style.md +++ b/docs/the_black_code_style/future_style.md @@ -9,15 +9,6 @@ CLI flag. At the end of each year, these changes may be adopted into the default as described in [The Black Code Style](index.md). Because the functionality is experimental, feedback and issue reports are highly encouraged! -In the past, the preview style included some features with known bugs, so that we were -unable to move these features to the stable style. Therefore, such features are now -moved to the `--unstable` style. All features in the `--preview` style are expected to -make it to next year's stable style; features in the `--unstable` style will be -stabilized only if issues with them are fixed. If bugs are discovered in a `--preview` -feature, it is demoted to the `--unstable` style. To avoid thrash when a feature is -demoted from the `--preview` to the `--unstable` style, users can use the -`--enable-unstable-feature` flag to enable specific unstable features. - (labels/preview-features)= Currently, the following features are included in the preview style: @@ -35,17 +26,8 @@ Currently, the following features are included in the preview style: types in `except` and `except*` without `as`. See PEP 758 for details. - `normalize_cr_newlines`: Add `\r` style newlines to the potential newlines to normalize file newlines both from and to. - -(labels/unstable-features)= - -The unstable style additionally includes the following features: - -- `string_processing`: split long string literals and related changes - ([see below](labels/string-processing)) - `multiline_string_handling`: more compact formatting of expressions involving multiline strings ([see below](labels/multiline-string-handling)) -- `hug_parens_with_braces_and_square_brackets`: more compact formatting of nested - brackets ([see below](labels/hug-parens)) (labels/wrap-long-dict-values)= @@ -74,6 +56,76 @@ my_dict = { } ``` +(labels/multiline-string-handling)= + +### Improved multiline string handling + +_Black_ is smarter when formatting multiline strings, especially in function arguments, +to avoid introducing extra line breaks. Previously, it would always consider multiline +strings as not fitting on a single line. With this new feature, _Black_ looks at the +context around the multiline string to decide if it should be inlined or split to a +separate line. For example, when a multiline string is passed to a function, _Black_ +will only split the multiline string if a line is too long or if multiple arguments are +being passed. + +For example, _Black_ will reformat + +```python +textwrap.dedent( + """\ + This is a + multiline string +""" +) +``` + +to: + +```python +textwrap.dedent("""\ + This is a + multiline string +""") +``` + +And: + +```python +MULTILINE = """ +foobar +""".replace( + "\n", "" +) +``` + +to: + +```python +MULTILINE = """ +foobar +""".replace("\n", "") +``` + +(labels/unstable-features)= + +## Unstable style + +In the past, the preview style included some features with known bugs, so that we were +unable to move these features to the stable style. Therefore, such features are now +moved to the `--unstable` style. All features in the `--preview` style are expected to +make it to next year's stable style; features in the `--unstable` style will be +stabilized only if issues with them are fixed. If bugs are discovered in a `--preview` +feature, it is demoted to the `--unstable` style. To avoid thrash when a feature is +demoted from the `--preview` to the `--unstable` style, users can use the +`--enable-unstable-feature` flag to enable specific unstable features. + +The unstable style additionally includes the following features: + +- `hug_parens_with_braces_and_square_brackets`: more compact formatting of nested + brackets ([see below](labels/hug-parens)) +- `string_processing`: split long string literals and related changes + ([see below](labels/string-processing)) + (labels/hug-parens)= ### Improved multiline dictionary and list indentation for sole function parameter @@ -155,121 +207,6 @@ foo( _Black_ will split long string literals and merge short ones. Parentheses are used where appropriate. When split, parts of f-strings that don't need formatting are converted to plain strings. f-strings will not be merged if they contain internal quotes and it would -change their quotation mark style. User-made splits are respected when they do not -exceed the line length limit. Line continuation backslashes are converted into +change their quotation mark style. Line continuation backslashes are converted into parenthesized strings. Unnecessary parentheses are stripped. The stability and status of this feature is tracked in [this issue](https://github.com/psf/black/issues/2188). - -(labels/multiline-string-handling)= - -### Improved multiline string handling - -_Black_ is smarter when formatting multiline strings, especially in function arguments, -to avoid introducing extra line breaks. Previously, it would always consider multiline -strings as not fitting on a single line. With this new feature, _Black_ looks at the -context around the multiline string to decide if it should be inlined or split to a -separate line. For example, when a multiline string is passed to a function, _Black_ -will only split the multiline string if a line is too long or if multiple arguments are -being passed. - -For example, _Black_ will reformat - -```python -textwrap.dedent( - """\ - This is a - multiline string -""" -) -``` - -to: - -```python -textwrap.dedent("""\ - This is a - multiline string -""") -``` - -And: - -```python -MULTILINE = """ -foobar -""".replace( - "\n", "" -) -``` - -to: - -```python -MULTILINE = """ -foobar -""".replace("\n", "") -``` - -Implicit multiline strings are special, because they can have inline comments. Strings -without comments are merged, for example - -```python -s = ( - "An " - "implicit " - "multiline " - "string" -) -``` - -becomes - -```python -s = "An implicit multiline string" -``` - -A comment on any line of the string (or between two string lines) will block the -merging, so - -```python -s = ( - "An " # Important comment concerning just this line - "implicit " - "multiline " - "string" -) -``` - -and - -```python -s = ( - "An " - "implicit " - # Comment in between - "multiline " - "string" -) -``` - -will not be merged. Having the comment after or before the string lines (but still -inside the parens) will merge the string. For example - -```python -s = ( # Top comment - "An " - "implicit " - "multiline " - "string" - # Bottom comment -) -``` - -becomes - -```python -s = ( # Top comment - "An implicit multiline string" - # Bottom comment -) -``` diff --git a/tests/data/cases/preview_multiline_strings.py b/tests/data/cases/preview_multiline_strings.py index e441fdc4ff8..eb0c72294c9 100644 --- a/tests/data/cases/preview_multiline_strings.py +++ b/tests/data/cases/preview_multiline_strings.py @@ -1,4 +1,4 @@ -# flags: --unstable +# flags: --preview """cow say""", call(3, "dogsay", textwrap.dedent("""dove @@ -157,23 +157,6 @@ def dastardly_default_value( `--global-option` is reserved to flags like `--verbose` or `--quiet`. """ -this_will_become_one_line = ( - "a" - "b" - "c" -) - -this_will_stay_on_three_lines = ( - "a" # comment - "b" - "c" -) - -this_will_also_become_one_line = ( # comment - "a" - "b" - "c" -) assert some_var == expected_result, """ test @@ -451,16 +434,6 @@ def dastardly_default_value( `--global-option` is reserved to flags like `--verbose` or `--quiet`. """ -this_will_become_one_line = "abc" - -this_will_stay_on_three_lines = ( - "a" # comment - "b" - "c" -) - -this_will_also_become_one_line = "abc" # comment - assert some_var == expected_result, """ test """ From d5756a55e86320c8c42408a508bbe4e92044a6e5 Mon Sep 17 00:00:00 2001 From: cobalt <61329810+cobaltt7@users.noreply.github.com> Date: Sat, 20 Sep 2025 14:29:12 -0500 Subject: [PATCH 3/4] fix tests Signed-off-by: cobalt <61329810+cobaltt7@users.noreply.github.com> --- docs/the_black_code_style/future_style.md | 6 ++++-- tests/data/cases/preview_multiline_strings.py | 1 - 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/the_black_code_style/future_style.md b/docs/the_black_code_style/future_style.md index bf88ec24dcd..5b98fcb5064 100644 --- a/docs/the_black_code_style/future_style.md +++ b/docs/the_black_code_style/future_style.md @@ -106,10 +106,10 @@ foobar """.replace("\n", "") ``` -(labels/unstable-features)= - ## Unstable style +(labels/unstable-style)= + In the past, the preview style included some features with known bugs, so that we were unable to move these features to the stable style. Therefore, such features are now moved to the `--unstable` style. All features in the `--preview` style are expected to @@ -119,6 +119,8 @@ feature, it is demoted to the `--unstable` style. To avoid thrash when a feature demoted from the `--preview` to the `--unstable` style, users can use the `--enable-unstable-feature` flag to enable specific unstable features. +(labels/unstable-features)= + The unstable style additionally includes the following features: - `hug_parens_with_braces_and_square_brackets`: more compact formatting of nested diff --git a/tests/data/cases/preview_multiline_strings.py b/tests/data/cases/preview_multiline_strings.py index eb0c72294c9..9596357b287 100644 --- a/tests/data/cases/preview_multiline_strings.py +++ b/tests/data/cases/preview_multiline_strings.py @@ -157,7 +157,6 @@ def dastardly_default_value( `--global-option` is reserved to flags like `--verbose` or `--quiet`. """ - assert some_var == expected_result, """ test """ From 7e8a7f22d9ee21715ebdd875c5cafa101c75856f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 26 Sep 2025 04:10:20 +0000 Subject: [PATCH 4/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- docs/the_black_code_style/future_style.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/the_black_code_style/future_style.md b/docs/the_black_code_style/future_style.md index 0bccc3852d3..46477638824 100644 --- a/docs/the_black_code_style/future_style.md +++ b/docs/the_black_code_style/future_style.md @@ -30,7 +30,7 @@ Currently, the following features are included in the preview style: multiline strings ([see below](labels/multiline-string-handling)) - `fix_module_docstring_detection`: Fix module docstrings being treated as normal strings if preceeded by comments. - + (labels/wrap-long-dict-values)= ### Improved parentheses management in dicts