- Fix handling of standalone `match()` or `case()` when there is a trailing newline or a
comment inside of the parentheses. (#2760)
- Black now normalizes string prefix order (#2297)
+- Deprecate `--experimental-string-processing` and move the functionality under
+ `--preview` (#2789)
### Packaging
### Preview style
-- Introduce the `--preview` flag with no style changes (#2752)
+- Introduce the `--preview` flag (#2752)
+- Add `--experimental-string-processing` to the preview style (#2789)
### Integrations
Starting in 2022, the formatting output will be stable for the releases made in the same
year (other than unintentional bugs). It is possible to opt-in to the latest formatting
-styles, using the `--future` flag.
+styles, using the `--preview` flag.
## Why is my file not formatted?
[YAPF](https://github.com/google/yapf)'s block comments to the same effect, as a
courtesy for straddling code.
+The rest of this document describes the current formatting style. If you're interested
+in trying out where the style is heading, see [future style](./future_style.md) and try
+running `black --preview`.
+
### How _Black_ wraps lines
_Black_ ignores previous formatting and applies uniform horizontal and vertical
you can pass `--skip-string-normalization` on the command line. This is meant as an
adoption helper, avoid using this for new projects.
-(labels/experimental-string)=
-
-As an experimental option (can be enabled by `--experimental-string-processing`),
-_Black_ splits long strings (using parentheses where appropriate) and merges short ones.
-When split, parts of f-strings that don't need formatting are converted to plain
-strings. User-made splits are respected when they do not exceed the line length limit.
-Line continuation backslashes are converted into parenthesized strings. Unnecessary
-parentheses are stripped. Because the functionality is experimental, feedback and issue
-reports are highly encouraged!
-
_Black_ also processes docstrings. Firstly the indentation of docstrings is corrected
for both quotations and the text within, although relative indentation in the text is
preserved. Superfluous trailing whitespace on each line and unnecessary new lines at the
Although when the target version is Python 3.9 or higher, _Black_ will use parentheses
instead since they're allowed in Python 3.9 and higher.
-## Improved string processing
-
-Currently, _Black_ does not split long strings to fit the line length limit. Currently,
-there is [an experimental option](labels/experimental-string) to enable splitting
-strings. We plan to enable this option by default once it is fully stable. This is
-tracked in [this issue](https://github.com/psf/black/issues/2188).
-
## Preview style
Experimental, potentially disruptive style changes are gathered under the `--preview`
CLI flag. At the end of each year, these changes may be adopted into the default style,
-as described in [The Black Code Style](./index.rst).
+as described in [The Black Code Style](./index.rst). Because the functionality is
+experimental, feedback and issue reports are highly encouraged!
+
+### Improved string processing
+
+_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. User-made splits are respected when they do not exceed the line length
+limit. 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).
"--experimental-string-processing",
is_flag=True,
hidden=True,
- help=(
- "Experimental option that performs more normalization on string literals."
- " Currently disabled because it leads to some crashes."
- ),
+ help="(DEPRECATED and now included in --preview) Normalize string literals.",
)
@click.option(
"--preview",
from black.strings import normalize_string_prefix, normalize_string_quotes
from black.trans import Transformer, CannotTransform, StringMerger
from black.trans import StringSplitter, StringParenWrapper, StringParenStripper
-from black.mode import Mode
-from black.mode import Feature
+from black.mode import Mode, Feature, Preview
from blib2to3.pytree import Node, Leaf
from blib2to3.pgen2 import token
and not (line.inside_brackets and line.contains_standalone_comments())
):
# Only apply basic string preprocessing, since lines shouldn't be split here.
- if mode.experimental_string_processing:
+ if Preview.string_processing in mode:
transformers = [string_merge, string_paren_strip]
else:
transformers = []
# via type ... https://github.com/mypyc/mypyc/issues/884
rhs = type("rhs", (), {"__call__": _rhs})()
- if mode.experimental_string_processing:
+ if Preview.string_processing in mode:
if line.inside_brackets:
transformers = [
string_merge,
import sys
from dataclasses import dataclass, field
-from enum import Enum
+from enum import Enum, auto
from operator import attrgetter
from typing import Dict, Set
+from warnings import warn
if sys.version_info < (3, 8):
from typing_extensions import Final
class Preview(Enum):
"""Individual preview style features."""
+ string_processing = auto()
+ hug_simple_powers = auto()
+
+
+class Deprecated(UserWarning):
+ """Visible deprecation warning."""
+
@dataclass
class Mode:
experimental_string_processing: bool = False
preview: bool = False
+ def __post_init__(self) -> None:
+ if self.experimental_string_processing:
+ warn(
+ "`experimental string processing` has been included in `preview`"
+ " and deprecated. Use `preview` instead.",
+ Deprecated,
+ )
+
def __contains__(self, feature: Preview) -> bool:
"""
Provide `Preview.FEATURE in Mode` syntax that mirrors the ``preview`` flag.
The argument is not checked and features are not differentiated.
They only exist to make development easier by clarifying intent.
"""
+ if feature is Preview.string_processing:
+ return self.preview or self.experimental_string_processing
return self.preview
def get_cache_key(self) -> str:
os.unlink(tmp_file)
self.assertFormatEqual(expected, actual)
+ def test_experimental_string_processing_warns(self) -> None:
+ self.assertWarns(
+ black.mode.Deprecated, black.Mode, experimental_string_processing=True
+ )
+
def test_piping(self) -> None:
source, expected = read_data("src/black/__init__", data=False)
result = BlackRunner().invoke(
@patch("black.dump_to_file", dump_to_stderr)
def test_string_quotes(self) -> None:
source, expected = read_data("string_quotes")
- mode = black.Mode(experimental_string_processing=True)
+ mode = black.Mode(preview=True)
assert_format(source, expected, mode)
mode = replace(mode, string_normalization=False)
not_normalized = fs(source, mode=mode)
"tupleassign",
]
-EXPERIMENTAL_STRING_PROCESSING_CASES: List[str] = [
- "cantfit",
- "comments7",
- "long_strings",
- "long_strings__edge_case",
- "long_strings__regression",
- "percent_precedence",
-]
-
PY310_CASES: List[str] = [
"pattern_matching_simple",
"pattern_matching_complex",
"parenthesized_context_managers",
]
-PREVIEW_CASES: List[str] = []
+PREVIEW_CASES: List[str] = [
+ # string processing
+ "cantfit",
+ "comments7",
+ "long_strings",
+ "long_strings__edge_case",
+ "long_strings__regression",
+ "percent_precedence",
+]
SOURCES: List[str] = [
"src/black/__init__.py",
check_file(filename, DEFAULT_MODE)
-@pytest.mark.parametrize("filename", EXPERIMENTAL_STRING_PROCESSING_CASES)
-def test_experimental_format(filename: str) -> None:
- check_file(filename, black.Mode(experimental_string_processing=True))
-
-
@pytest.mark.parametrize("filename", PREVIEW_CASES)
def test_preview_format(filename: str) -> None:
check_file(filename, black.Mode(preview=True))