Create --preview CLI flag (#2752)

This commit is contained in:
Felix Hildén 2022-01-20 03:34:52 +02:00 committed by GitHub
parent 98db4abc21
commit 8c22d232b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 51 additions and 7 deletions

View File

@ -36,6 +36,10 @@
- All upper version bounds on dependencies have been removed (#2718) - All upper version bounds on dependencies have been removed (#2718)
- `typing-extensions` is no longer a required dependency in Python 3.10+ (#2772) - `typing-extensions` is no longer a required dependency in Python 3.10+ (#2772)
### Preview style
- Introduce the `--preview` flag with no style changes (#2752)
### Integrations ### Integrations
- Update GitHub action to support containerized runs (#2748) - Update GitHub action to support containerized runs (#2748)

View File

@ -55,7 +55,9 @@ go back and workout what to add to the `CHANGES.md` for each release.
If a change would affect the advertised code style, please modify the documentation (The If a change would affect the advertised code style, please modify the documentation (The
_Black_ code style) to reflect that change. Patches that fix unintended bugs in _Black_ code style) to reflect that change. Patches that fix unintended bugs in
formatting don't need to be mentioned separately though. formatting don't need to be mentioned separately though. If the change is implemented
with the `--preview` flag, please include the change in the future style document
instead and write the changelog entry under a dedicated "Preview changes" heading.
### Docs Testing ### Docs Testing

View File

@ -40,3 +40,9 @@ Currently, _Black_ does not split long strings to fit the line length limit. Cur
there is [an experimental option](labels/experimental-string) to enable splitting 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 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). 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).

View File

@ -32,7 +32,7 @@ versions of *Black*:
improved formatting enabled by newer Python language syntax as well as due improved formatting enabled by newer Python language syntax as well as due
to improvements in the formatting logic. to improvements in the formatting logic.
- The ``--future`` flag is exempt from this policy. There are no guarantees - The ``--preview`` flag is exempt from this policy. There are no guarantees
around the stability of the output with that flag passed into *Black*. This around the stability of the output with that flag passed into *Black*. This
flag is intended for allowing experimentation with the proposed changes to flag is intended for allowing experimentation with the proposed changes to
the *Black* code style. the *Black* code style.

View File

@ -246,6 +246,14 @@ def validate_regex(
" Currently disabled because it leads to some crashes." " Currently disabled because it leads to some crashes."
), ),
) )
@click.option(
"--preview",
is_flag=True,
help=(
"Enable potentially disruptive style changes that will be added to Black's main"
" functionality in the next major release."
),
)
@click.option( @click.option(
"--check", "--check",
is_flag=True, is_flag=True,
@ -399,6 +407,7 @@ def main(
skip_string_normalization: bool, skip_string_normalization: bool,
skip_magic_trailing_comma: bool, skip_magic_trailing_comma: bool,
experimental_string_processing: bool, experimental_string_processing: bool,
preview: bool,
quiet: bool, quiet: bool,
verbose: bool, verbose: bool,
required_version: Optional[str], required_version: Optional[str],
@ -469,6 +478,7 @@ def main(
string_normalization=not skip_string_normalization, string_normalization=not skip_string_normalization,
magic_trailing_comma=not skip_magic_trailing_comma, magic_trailing_comma=not skip_magic_trailing_comma,
experimental_string_processing=experimental_string_processing, experimental_string_processing=experimental_string_processing,
preview=preview,
) )
if code is not None: if code is not None:

View File

@ -121,6 +121,10 @@ def supports_feature(target_versions: Set[TargetVersion], feature: Feature) -> b
return all(feature in VERSION_TO_FEATURES[version] for version in target_versions) return all(feature in VERSION_TO_FEATURES[version] for version in target_versions)
class Preview(Enum):
"""Individual preview style features."""
@dataclass @dataclass
class Mode: class Mode:
target_versions: Set[TargetVersion] = field(default_factory=set) target_versions: Set[TargetVersion] = field(default_factory=set)
@ -130,6 +134,16 @@ class Mode:
is_ipynb: bool = False is_ipynb: bool = False
magic_trailing_comma: bool = True magic_trailing_comma: bool = True
experimental_string_processing: bool = False experimental_string_processing: bool = False
preview: bool = False
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.
"""
return self.preview
def get_cache_key(self) -> str: def get_cache_key(self) -> str:
if self.target_versions: if self.target_versions:
@ -147,5 +161,6 @@ def get_cache_key(self) -> str:
str(int(self.is_ipynb)), str(int(self.is_ipynb)),
str(int(self.magic_trailing_comma)), str(int(self.magic_trailing_comma)),
str(int(self.experimental_string_processing)), str(int(self.experimental_string_processing)),
str(int(self.preview)),
] ]
return ".".join(parts) return ".".join(parts)

View File

@ -1,5 +1,5 @@
from dataclasses import replace from dataclasses import replace
from typing import Any, Iterator from typing import Any, Iterator, List
from unittest.mock import patch from unittest.mock import patch
import pytest import pytest
@ -14,7 +14,7 @@
read_data, read_data,
) )
SIMPLE_CASES = [ SIMPLE_CASES: List[str] = [
"beginning_backslash", "beginning_backslash",
"bracketmatch", "bracketmatch",
"class_blank_parentheses", "class_blank_parentheses",
@ -55,7 +55,7 @@
"tupleassign", "tupleassign",
] ]
EXPERIMENTAL_STRING_PROCESSING_CASES = [ EXPERIMENTAL_STRING_PROCESSING_CASES: List[str] = [
"cantfit", "cantfit",
"comments7", "comments7",
"long_strings", "long_strings",
@ -64,7 +64,7 @@
"percent_precedence", "percent_precedence",
] ]
PY310_CASES = [ PY310_CASES: List[str] = [
"pattern_matching_simple", "pattern_matching_simple",
"pattern_matching_complex", "pattern_matching_complex",
"pattern_matching_extras", "pattern_matching_extras",
@ -73,7 +73,9 @@
"parenthesized_context_managers", "parenthesized_context_managers",
] ]
SOURCES = [ PREVIEW_CASES: List[str] = []
SOURCES: List[str] = [
"src/black/__init__.py", "src/black/__init__.py",
"src/black/__main__.py", "src/black/__main__.py",
"src/black/brackets.py", "src/black/brackets.py",
@ -139,6 +141,11 @@ def test_experimental_format(filename: str) -> None:
check_file(filename, black.Mode(experimental_string_processing=True)) 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))
@pytest.mark.parametrize("filename", SOURCES) @pytest.mark.parametrize("filename", SOURCES)
def test_source_is_formatted(filename: str) -> None: def test_source_is_formatted(filename: str) -> None:
path = THIS_DIR.parent / filename path = THIS_DIR.parent / filename