Skip to content

Commit

Permalink
Deprecate Python 2 formatting support
Browse files Browse the repository at this point in the history
  • Loading branch information
ichard26 committed Oct 30, 2021
1 parent 79acf4e commit 01cbded
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 5 deletions.
10 changes: 7 additions & 3 deletions docs/faq.md
Expand Up @@ -74,13 +74,17 @@ disabled-by-default counterpart W504. E203 should be disabled while changes are

## Does Black support Python 2?

```{warning}
Python 2 support has been deprecated since 21.10b0.
this support will be dropped in the first stable release, expected for January 2022.
See [The Black Code Style](the_black_code_style/index.rst) for details.
```

For formatting, yes! [Install](getting_started.md#installation) with the `python2` extra
to format Python 2 files too! In terms of running _Black_ though, Python 3.6 or newer is
required.

Note that this support will be dropped in the first stable release, expected for
January 2022. See [The Black Code Style](the_black_code_style/index.rst) for details.

## Why does my linter or typechecker complain after I format my code?

Some linters and other tools use magical comments (e.g., `# noqa`, `# type: ignore`) to
Expand Down
17 changes: 16 additions & 1 deletion src/black/__init__.py
Expand Up @@ -1058,6 +1058,15 @@ def f(
versions = mode.target_versions
else:
versions = detect_target_versions(src_node)

# TODO: fully drop support and this code hopefully in January 2022 :D
if TargetVersion.PY27 in mode.target_versions or versions == {TargetVersion.PY27}:
msg = (
"DEPRECATION: Python 2 support will be removed in the first stable release"
"expected in January 2022."
)
err(msg, fg="yellow", bold=True)

normalize_fmt_off(src_node)
lines = LineGenerator(
mode=mode,
Expand Down Expand Up @@ -1100,7 +1109,7 @@ def decode_bytes(src: bytes) -> Tuple[FileContent, Encoding, NewLine]:
return tiow.read(), encoding, newline


def get_features_used(node: Node) -> Set[Feature]:
def get_features_used(node: Node) -> Set[Feature]: # noqa: C901
"""Return a set of (relatively) new Python features used in this file.
Currently looking for:
Expand All @@ -1110,6 +1119,7 @@ def get_features_used(node: Node) -> Set[Feature]:
- positional only arguments in function signatures and lambdas;
- assignment expression;
- relaxed decorator syntax;
- print / exec statements;
"""
features: Set[Feature] = set()
for n in node.pre_order():
Expand Down Expand Up @@ -1158,6 +1168,11 @@ def get_features_used(node: Node) -> Set[Feature]:
if argch.type in STARS:
features.add(feature)

elif n.type == token.PRINT_STMT:
features.add(Feature.PRINT_STMT)
elif n.type == token.EXEC_STMT:
features.add(Feature.EXEC_STMT)

return features


Expand Down
10 changes: 9 additions & 1 deletion src/black/mode.py
Expand Up @@ -41,9 +41,17 @@ class Feature(Enum):
RELAXED_DECORATORS = 10
FORCE_OPTIONAL_PARENTHESES = 50

# temporary; for Python 2 deprecation
PRINT_STMT = 200
EXEC_STMT = 201


VERSION_TO_FEATURES: Dict[TargetVersion, Set[Feature]] = {
TargetVersion.PY27: {Feature.ASYNC_IDENTIFIERS},
TargetVersion.PY27: {
Feature.ASYNC_IDENTIFIERS,
Feature.PRINT_STMT,
Feature.EXEC_STMT,
},
TargetVersion.PY33: {Feature.UNICODE_LITERALS, Feature.ASYNC_IDENTIFIERS},
TargetVersion.PY34: {Feature.UNICODE_LITERALS, Feature.ASYNC_IDENTIFIERS},
TargetVersion.PY35: {
Expand Down
3 changes: 3 additions & 0 deletions src/blib2to3/pgen2/token.py
Expand Up @@ -74,6 +74,9 @@
COLONEQUAL: Final = 59
N_TOKENS: Final = 60
NT_OFFSET: Final = 256
# temporary for Python 2 deprecation
PRINT_STMT: Final = 316
EXEC_STMT: Final = 288
# --end constants--

tok_name: Final[Dict[int, str]] = {}
Expand Down
15 changes: 15 additions & 0 deletions tests/test_black.py
Expand Up @@ -2014,6 +2014,21 @@ def test_get_sources_with_stdin_filename_and_force_exclude(self) -> None:
)


@pytest.mark.parametrize("explicit", [True, False], ids=["explicit", "autodetection"])
def test_python_2_deprecation_with_target_version(explicit: bool) -> None:
args = [
"--config",
str(THIS_DIR / "empty.toml"),
str(DATA_DIR / "python2.py"),
"--check",
]
if explicit:
args.append("--target-version=py27")
with cache_dir():
result = BlackRunner().invoke(black.main, args)
assert "DEPRECATION: Python 2 support will be removed" in result.stderr


with open(black.__file__, "r", encoding="utf-8") as _bf:
black_source_lines = _bf.readlines()

Expand Down

0 comments on commit 01cbded

Please sign in to comment.