- All upper version bounds on dependencies have been removed (#2718)
- `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
- Update GitHub action to support containerized runs (#2748)
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
-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
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).
improved formatting enabled by newer Python language syntax as well as due
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
flag is intended for allowing experimentation with the proposed changes to
the *Black* code style.
" 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(
"--check",
is_flag=True,
skip_string_normalization: bool,
skip_magic_trailing_comma: bool,
experimental_string_processing: bool,
+ preview: bool,
quiet: bool,
verbose: bool,
required_version: Optional[str],
string_normalization=not skip_string_normalization,
magic_trailing_comma=not skip_magic_trailing_comma,
experimental_string_processing=experimental_string_processing,
+ preview=preview,
)
if code is not None:
return all(feature in VERSION_TO_FEATURES[version] for version in target_versions)
+class Preview(Enum):
+ """Individual preview style features."""
+
+
@dataclass
class Mode:
target_versions: Set[TargetVersion] = field(default_factory=set)
is_ipynb: bool = False
magic_trailing_comma: bool = True
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:
if self.target_versions:
str(int(self.is_ipynb)),
str(int(self.magic_trailing_comma)),
str(int(self.experimental_string_processing)),
+ str(int(self.preview)),
]
return ".".join(parts)
from dataclasses import replace
-from typing import Any, Iterator
+from typing import Any, Iterator, List
from unittest.mock import patch
import pytest
read_data,
)
-SIMPLE_CASES = [
+SIMPLE_CASES: List[str] = [
"beginning_backslash",
"bracketmatch",
"class_blank_parentheses",
"tupleassign",
]
-EXPERIMENTAL_STRING_PROCESSING_CASES = [
+EXPERIMENTAL_STRING_PROCESSING_CASES: List[str] = [
"cantfit",
"comments7",
"long_strings",
"percent_precedence",
]
-PY310_CASES = [
+PY310_CASES: List[str] = [
"pattern_matching_simple",
"pattern_matching_complex",
"pattern_matching_extras",
"parenthesized_context_managers",
]
-SOURCES = [
+PREVIEW_CASES: List[str] = []
+
+SOURCES: List[str] = [
"src/black/__init__.py",
"src/black/__main__.py",
"src/black/brackets.py",
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)
def test_source_is_formatted(filename: str) -> None:
path = THIS_DIR.parent / filename