WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit 52de08f

Browse files
committed
Merge branch 'feat/pyproject-config' of https://github.com/Shivansh-007/black into feat/pyproject-config
2 parents cb36ae6 + 7ed5e3f commit 52de08f

18 files changed

+326
-140
lines changed

CHANGES.md

Lines changed: 52 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,41 +2,59 @@
22

33
## Unreleased
44

5-
### _Black_
5+
At long last, _Black_ is no longer a beta product! This is the first non-beta release
6+
and the first release covered by our new stability policy.
7+
8+
### Highlights
69

710
- **Remove Python 2 support** (#2740)
8-
- Do not accept bare carriage return line endings in pyproject.toml (#2408)
9-
- Improve error message for invalid regular expression (#2678)
10-
- Improve error message when parsing fails during AST safety check by embedding the
11-
underlying SyntaxError (#2693)
11+
- Introduce the `--preview` flag (#2752)
12+
13+
### Style
14+
15+
- Deprecate `--experimental-string-processing` and move the functionality under
16+
`--preview` (#2789)
17+
- For stubs, one blank line between class attributes and methods is now kept if there's
18+
at least one pre-existing blank line (#2736)
19+
- Black now normalizes string prefix order (#2297)
20+
- Remove spaces around power operators if both operands are simple (#2726)
21+
- Work around bug that causes unstable formatting in some cases in the presence of the
22+
magic trailing comma (#2807)
23+
- Use parentheses for attribute access on decimal float and int literals (#2799)
24+
- Don't add whitespace for attribute access on hexadecimal, binary, octal, and complex
25+
literals (#2799)
26+
- Treat blank lines in stubs the same inside top-level `if` statements (#2820)
27+
- Fix unstable formatting with semicolons and arithmetic expressions (#2817)
28+
29+
### Parser
30+
1231
- Fix mapping cases that contain as-expressions, like `case {"key": 1 | 2 as password}`
1332
(#2686)
1433
- Fix cases that contain multiple top-level as-expressions, like `case 1 as a, 2 as b`
1534
(#2716)
1635
- Fix call patterns that contain as-expressions with keyword arguments, like
1736
`case Foo(bar=baz as quux)` (#2749)
18-
- No longer color diff headers white as it's unreadable in light themed terminals
19-
(#2691)
2037
- Tuple unpacking on `return` and `yield` constructs now implies 3.8+ (#2700)
2138
- Unparenthesized tuples on annotated assignments (e.g
2239
`values: Tuple[int, ...] = 1, 2, 3`) now implies 3.8+ (#2708)
23-
- Remove spaces around power operators if both operands are simple (#2726)
24-
- Allow setting custom cache directory on all platforms with environment variable
25-
`BLACK_CACHE_DIR` (#2739).
26-
- Text coloring added in the final statistics (#2712)
27-
- For stubs, one blank line between class attributes and methods is now kept if there's
28-
at least one pre-existing blank line (#2736)
29-
- Verbose mode also now describes how a project root was discovered and which paths will
30-
be formatted. (#2526)
31-
- Speed-up the new backtracking parser about 4X in general (enabled when
32-
`--target-version` is set to 3.10 and higher). (#2728)
3340
- Fix handling of standalone `match()` or `case()` when there is a trailing newline or a
3441
comment inside of the parentheses. (#2760)
35-
- Black now normalizes string prefix order (#2297)
42+
43+
### Performance
44+
45+
- Speed-up the new backtracking parser about 4X in general (enabled when
46+
`--target-version` is set to 3.10 and higher). (#2728)
47+
- _Black_ is now compiled with [mypyc](https://github.com/mypyc/mypyc) for an overall 2x
48+
speed-up. 64-bit Windows, MacOS, and Linux (not including musl) are supported. (#1009,
49+
#2431)
50+
51+
### Configuration
52+
53+
- Do not accept bare carriage return line endings in pyproject.toml (#2408)
3654
- Add configuration option (`python-cell-magics`) to format cells with custom magics in
3755
Jupyter Notebooks (#2744)
38-
- Deprecate `--experimental-string-processing` and move the functionality under
39-
`--preview` (#2789)
56+
- Allow setting custom cache directory on all platforms with environment variable
57+
`BLACK_CACHE_DIR` (#2739).
4058
- Enable Python 3.10+ by default, without any extra need to specify
4159
`--target-version=py310`. (#2758)
4260
- Make passing `SRC` or `--code` mandatory and mutually exclusive (#2804)
@@ -48,17 +66,23 @@
4866
- Deprecate the `black-primer` tool (#2809)
4967
- Allow specifying `config` in config files to include configuration options (#2525)
5068

69+
### Output
70+
71+
- Improve error message for invalid regular expression (#2678)
72+
- Improve error message when parsing fails during AST safety check by embedding the
73+
underlying SyntaxError (#2693)
74+
- No longer color diff headers white as it's unreadable in light themed terminals
75+
(#2691)
76+
- Text coloring added in the final statistics (#2712)
77+
- Verbose mode also now describes how a project root was discovered and which paths will
78+
be formatted. (#2526)
79+
5180
### Packaging
5281

5382
- All upper version bounds on dependencies have been removed (#2718)
5483
- `typing-extensions` is no longer a required dependency in Python 3.10+ (#2772)
5584
- Set `click` lower bound to `8.0.0` (#2791)
5685

57-
### Preview style
58-
59-
- Introduce the `--preview` flag (#2752)
60-
- Add `--experimental-string-processing` to the preview style (#2789)
61-
6286
### Integrations
6387

6488
- Update GitHub action to support containerized runs (#2748)
@@ -68,6 +92,8 @@
6892
- Change protocol in pip installation instructions to `https://` (#2761)
6993
- Change HTML theme to Furo primarily for its responsive design and mobile support
7094
(#2793)
95+
- Deprecate the `black-primer` tool (#2809)
96+
- Document Python support policy (#2819)
7197

7298
## 21.12b0
7399

@@ -120,6 +146,7 @@
120146
when `--target-version py310` is explicitly specified (#2586)
121147
- Add support for parenthesized with (#2586)
122148
- Declare support for Python 3.10 for running Black (#2562)
149+
- Fix unstable black runs around magic trailing comma (#2572)
123150

124151
### Integrations
125152

docs/faq.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,16 @@ readability because operators are misaligned. Disable W503 and enable the
7171
disabled-by-default counterpart W504. E203 should be disabled while changes are still
7272
[discussed](https://github.com/PyCQA/pycodestyle/issues/373).
7373

74-
## Does Black support Python 2?
74+
## Which Python versions does Black support?
7575

76-
Support for formatting Python 2 code was removed in version 22.0.
76+
Currently the runtime requires Python 3.6-3.10. Formatting is supported for files
77+
containing syntax from Python 3.3 to 3.10. We promise to support at least all Python
78+
versions that have not reached their end of life. This is the case for both running
79+
_Black_ and formatting code.
80+
81+
Support for formatting Python 2 code was removed in version 22.0. While we've made no
82+
plans to stop supporting older Python 3 minor versions immediately, their support might
83+
also be removed some time in the future without a deprecation period.
7784

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

docs/the_black_code_style/current_style.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@
22

33
## Code style
44

5-
_Black_ reformats entire files in place. Style configuration options are deliberately
6-
limited and rarely added. It doesn't take previous formatting into account, except for
7-
the magic trailing comma and preserving newlines. It doesn't reformat blocks that start
8-
with `# fmt: off` and end with `# fmt: on`, or lines that ends with `# fmt: skip`.
5+
_Black_ aims for consistency, generality, readability and reducing git diffs. Similar
6+
language constructs are formatted with similar rules. Style configuration options are
7+
deliberately limited and rarely added. Previous formatting is taken into account as
8+
little as possible, with rare exceptions like the magic trailing comma. The coding style
9+
used by _Black_ can be viewed as a strict subset of PEP 8.
10+
11+
_Black_ reformats entire files in place. It doesn't reformat blocks that start with
12+
`# fmt: off` and end with `# fmt: on`, or lines that ends with `# fmt: skip`.
913
`# fmt: on/off` have to be on the same level of indentation. It also recognizes
1014
[YAPF](https://github.com/google/yapf)'s block comments to the same effect, as a
1115
courtesy for straddling code.
@@ -18,8 +22,7 @@ running `black --preview`.
1822

1923
_Black_ ignores previous formatting and applies uniform horizontal and vertical
2024
whitespace to your code. The rules for horizontal whitespace can be summarized as: do
21-
whatever makes `pycodestyle` happy. The coding style used by _Black_ can be viewed as a
22-
strict subset of PEP 8.
25+
whatever makes `pycodestyle` happy.
2326

2427
As for vertical whitespace, _Black_ tries to render one full expression or simple
2528
statement per line. If this fits the allotted line length, great.

docs/the_black_code_style/index.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ The Black Code Style
1212
While keeping the style unchanged throughout releases has always been a goal,
1313
the *Black* code style isn't set in stone. It evolves to accommodate for new features
1414
in the Python language and, occasionally, in response to user feedback.
15+
Large-scale style preferences presented in :doc:`current_style` are very unlikely to
16+
change, but minor style aspects and details might change according to the stability
17+
policy presented below. Ongoing style considerations are tracked on GitHub with the
18+
`design <https://github.com/psf/black/labels/T%3A%20design>`_ issue label.
1519

1620
Stability Policy
1721
----------------

fuzz.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def test_idempotent_any_syntatically_valid_python(
4848
dst_contents = black.format_str(src_contents, mode=mode)
4949
except black.InvalidInput:
5050
# This is a bug - if it's valid Python code, as above, Black should be
51-
# able to cope with it. See issues #970, #1012, #1358, and #1557.
51+
# able to cope with it. See issues #970, #1012
5252
# TODO: remove this try-except block when issues are resolved.
5353
return
5454
except TokenError as e:

src/black/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1348,7 +1348,7 @@ def get_imports_from_children(children: List[LN]) -> Generator[str, None, None]:
13481348
return imports
13491349

13501350

1351-
def assert_equivalent(src: str, dst: str, *, pass_num: int = 1) -> None:
1351+
def assert_equivalent(src: str, dst: str) -> None:
13521352
"""Raise AssertionError if `src` and `dst` aren't equivalent."""
13531353
try:
13541354
src_ast = parse_ast(src)
@@ -1365,7 +1365,7 @@ def assert_equivalent(src: str, dst: str, *, pass_num: int = 1) -> None:
13651365
except Exception as exc:
13661366
log = dump_to_file("".join(traceback.format_tb(exc.__traceback__)), dst)
13671367
raise AssertionError(
1368-
f"INTERNAL ERROR: Black produced invalid code on pass {pass_num}: {exc}. "
1368+
f"INTERNAL ERROR: Black produced invalid code: {exc}. "
13691369
"Please report a bug on https://github.com/psf/black/issues. "
13701370
f"This invalid output might be helpful: {log}"
13711371
) from None
@@ -1376,7 +1376,7 @@ def assert_equivalent(src: str, dst: str, *, pass_num: int = 1) -> None:
13761376
log = dump_to_file(diff(src_ast_str, dst_ast_str, "src", "dst"))
13771377
raise AssertionError(
13781378
"INTERNAL ERROR: Black produced code that is not equivalent to the"
1379-
f" source on pass {pass_num}. Please report a bug on "
1379+
f" source. Please report a bug on "
13801380
f"https://github.com/psf/black/issues. This diff might be helpful: {log}"
13811381
) from None
13821382

src/black/linegen.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
from black.nodes import WHITESPACE, RARROW, STATEMENT, STANDALONE_COMMENT
99
from black.nodes import ASSIGNMENTS, OPENING_BRACKETS, CLOSING_BRACKETS
10-
from black.nodes import Visitor, syms, first_child_is_arith, ensure_visible
10+
from black.nodes import Visitor, syms, is_arith_like, ensure_visible
1111
from black.nodes import is_docstring, is_empty_tuple, is_one_tuple, is_one_tuple_between
1212
from black.nodes import is_name_token, is_lpar_token, is_rpar_token
1313
from black.nodes import is_walrus_assignment, is_yield, is_vararg, is_multiline_string
@@ -156,8 +156,12 @@ def visit_suite(self, node: Node) -> Iterator[Line]:
156156

157157
def visit_simple_stmt(self, node: Node) -> Iterator[Line]:
158158
"""Visit a statement without nested statements."""
159-
if first_child_is_arith(node):
160-
wrap_in_parentheses(node, node.children[0], visible=False)
159+
prev_type: Optional[int] = None
160+
for child in node.children:
161+
if (prev_type is None or prev_type == token.SEMI) and is_arith_like(child):
162+
wrap_in_parentheses(node, child, visible=False)
163+
prev_type = child.type
164+
161165
is_suite_like = node.parent and node.parent.type in STATEMENT
162166
if is_suite_like:
163167
if self.mode.is_pyi and is_stub_body(node):
@@ -539,7 +543,7 @@ def right_hand_split(
539543
# there are no standalone comments in the body
540544
and not body.contains_standalone_comments(0)
541545
# and we can actually remove the parens
542-
and can_omit_invisible_parens(body, line_length, omit_on_explode=omit)
546+
and can_omit_invisible_parens(body, line_length)
543547
):
544548
omit = {id(closing_bracket), *omit}
545549
try:

src/black/lines.py

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import sys
44
from typing import (
55
Callable,
6-
Collection,
76
Dict,
87
Iterator,
98
List,
@@ -22,7 +21,7 @@
2221
from black.nodes import STANDALONE_COMMENT, TEST_DESCENDANTS
2322
from black.nodes import BRACKETS, OPENING_BRACKETS, CLOSING_BRACKETS
2423
from black.nodes import syms, whitespace, replace_child, child_towards
25-
from black.nodes import is_multiline_string, is_import, is_type_comment, last_two_except
24+
from black.nodes import is_multiline_string, is_import, is_type_comment
2625
from black.nodes import is_one_tuple_between
2726

2827
# types
@@ -530,11 +529,11 @@ def _maybe_empty_lines_for_class_or_def(
530529
return 0, 0
531530

532531
if self.is_pyi:
533-
if self.previous_line.depth > current_line.depth:
534-
newlines = 0 if current_line.depth else 1
535-
elif current_line.is_class or self.previous_line.is_class:
536-
if current_line.depth:
532+
if current_line.is_class or self.previous_line.is_class:
533+
if self.previous_line.depth < current_line.depth:
537534
newlines = 0
535+
elif self.previous_line.depth > current_line.depth:
536+
newlines = 1
538537
elif current_line.is_stub_class and self.previous_line.is_stub_class:
539538
# No blank line between classes with an empty body
540539
newlines = 0
@@ -551,6 +550,8 @@ def _maybe_empty_lines_for_class_or_def(
551550
# Blank line between a block of functions (maybe with preceding
552551
# decorators) and a block of non-functions
553552
newlines = 1
553+
elif self.previous_line.depth > current_line.depth:
554+
newlines = 1
554555
else:
555556
newlines = 0
556557
else:
@@ -643,7 +644,6 @@ def can_be_split(line: Line) -> bool:
643644
def can_omit_invisible_parens(
644645
line: Line,
645646
line_length: int,
646-
omit_on_explode: Collection[LeafID] = (),
647647
) -> bool:
648648
"""Does `line` have a shape safe to reformat without optional parens around it?
649649
@@ -681,12 +681,6 @@ def can_omit_invisible_parens(
681681

682682
penultimate = line.leaves[-2]
683683
last = line.leaves[-1]
684-
if line.magic_trailing_comma:
685-
try:
686-
penultimate, last = last_two_except(line.leaves, omit=omit_on_explode)
687-
except LookupError:
688-
# Turns out we'd omit everything. We cannot skip the optional parentheses.
689-
return False
690684

691685
if (
692686
last.type == token.RPAR
@@ -708,10 +702,6 @@ def can_omit_invisible_parens(
708702
# unnecessary.
709703
return True
710704

711-
if line.magic_trailing_comma and penultimate.type == token.COMMA:
712-
# The rightmost non-omitted bracket pair is the one we want to explode on.
713-
return True
714-
715705
if _can_omit_closing_paren(line, last=last, line_length=line_length):
716706
return True
717707

src/black/nodes.py

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,11 @@
44

55
import sys
66
from typing import (
7-
Collection,
87
Generic,
98
Iterator,
109
List,
1110
Optional,
1211
Set,
13-
Tuple,
1412
TypeVar,
1513
Union,
1614
)
@@ -439,27 +437,6 @@ def prev_siblings_are(node: Optional[LN], tokens: List[Optional[NodeType]]) -> b
439437
return prev_siblings_are(node.prev_sibling, tokens[:-1])
440438

441439

442-
def last_two_except(leaves: List[Leaf], omit: Collection[LeafID]) -> Tuple[Leaf, Leaf]:
443-
"""Return (penultimate, last) leaves skipping brackets in `omit` and contents."""
444-
stop_after: Optional[Leaf] = None
445-
last: Optional[Leaf] = None
446-
for leaf in reversed(leaves):
447-
if stop_after:
448-
if leaf is stop_after:
449-
stop_after = None
450-
continue
451-
452-
if last:
453-
return leaf, last
454-
455-
if id(leaf) in omit:
456-
stop_after = leaf.opening_bracket
457-
else:
458-
last = leaf
459-
else:
460-
raise LookupError("Last two leaves were also skipped")
461-
462-
463440
def parent_type(node: Optional[LN]) -> Optional[NodeType]:
464441
"""
465442
Returns:
@@ -531,15 +508,14 @@ def first_leaf_column(node: Node) -> Optional[int]:
531508
return None
532509

533510

534-
def first_child_is_arith(node: Node) -> bool:
535-
"""Whether first child is an arithmetic or a binary arithmetic expression"""
536-
expr_types = {
511+
def is_arith_like(node: LN) -> bool:
512+
"""Whether node is an arithmetic or a binary arithmetic expression"""
513+
return node.type in {
537514
syms.arith_expr,
538515
syms.shift_expr,
539516
syms.xor_expr,
540517
syms.and_expr,
541518
}
542-
return bool(node.children and node.children[0].type in expr_types)
543519

544520

545521
def is_docstring(leaf: Leaf) -> bool:

0 commit comments

Comments
 (0)