Skip to content

Commit

Permalink
Deprecate ESP and move the functionality under --preview (#2789)
Browse files Browse the repository at this point in the history
  • Loading branch information
felix-hilden committed Jan 20, 2022
1 parent 9bd4134 commit 6e97c5f
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 45 deletions.
5 changes: 4 additions & 1 deletion CHANGES.md
Expand Up @@ -30,6 +30,8 @@
- 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

Expand All @@ -38,7 +40,8 @@

### 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

Expand Down
2 changes: 1 addition & 1 deletion docs/faq.md
Expand Up @@ -33,7 +33,7 @@ still proposed on the issue tracker. See

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?

Expand Down
14 changes: 4 additions & 10 deletions docs/the_black_code_style/current_style.md
Expand Up @@ -10,6 +10,10 @@ with `# fmt: off` and end with `# fmt: on`, or lines that ends with `# fmt: skip
[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
Expand Down Expand Up @@ -260,16 +264,6 @@ If you are adopting _Black_ in a large project with pre-existing string conventi
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
Expand Down
19 changes: 11 additions & 8 deletions docs/the_black_code_style/future_style.md
Expand Up @@ -34,15 +34,18 @@ with \
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).
5 changes: 1 addition & 4 deletions src/black/__init__.py
Expand Up @@ -241,10 +241,7 @@ def validate_regex(
"--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",
Expand Down
7 changes: 3 additions & 4 deletions src/black/linegen.py
Expand Up @@ -23,8 +23,7 @@
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
Expand Down Expand Up @@ -338,7 +337,7 @@ def transform_line(
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 = []
Expand Down Expand Up @@ -381,7 +380,7 @@ def _rhs(
# 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,
Expand Down
20 changes: 19 additions & 1 deletion src/black/mode.py
Expand Up @@ -7,9 +7,10 @@
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
Expand Down Expand Up @@ -124,6 +125,13 @@ def supports_feature(target_versions: Set[TargetVersion], feature: Feature) -> b
class Preview(Enum):
"""Individual preview style features."""

string_processing = auto()
hug_simple_powers = auto()


class Deprecated(UserWarning):
"""Visible deprecation warning."""


@dataclass
class Mode:
Expand All @@ -136,13 +144,23 @@ 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:
Expand Down
7 changes: 6 additions & 1 deletion tests/test_black.py
Expand Up @@ -150,6 +150,11 @@ def test_empty_ff(self) -> None:
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(
Expand Down Expand Up @@ -342,7 +347,7 @@ def test_detect_pos_only_arguments(self) -> None:
@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)
Expand Down
24 changes: 9 additions & 15 deletions tests/test_format.py
Expand Up @@ -55,15 +55,6 @@
"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",
Expand All @@ -73,7 +64,15 @@
"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",
Expand Down Expand Up @@ -136,11 +135,6 @@ def test_simple_format(filename: str) -> None:
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))
Expand Down

0 comments on commit 6e97c5f

Please sign in to comment.