Skip to content

Commit

Permalink
Draft for Black 2023 stable style (#3418)
Browse files Browse the repository at this point in the history
  • Loading branch information
JelleZijlstra committed Jan 31, 2023
1 parent 226cbf0 commit c4bd2e3
Show file tree
Hide file tree
Showing 36 changed files with 207 additions and 274 deletions.
29 changes: 29 additions & 0 deletions CHANGES.md
Expand Up @@ -10,6 +10,35 @@

<!-- Changes that affect Black's stable style -->

- Introduce the 2023 stable style, which incorporates most aspects of last year's
preview style (#3418). Specific changes:
- Enforce empty lines before classes and functions with sticky leading comments
(#3302) (22.12.0)
- Reformat empty and whitespace-only files as either an empty file (if no newline is
present) or as a single newline character (if a newline is present) (#3348)
(22.12.0)
- Implicitly concatenated strings used as function args are now wrapped inside
parentheses (#3307) (22.12.0)
- Correctly handle trailing commas that are inside a line's leading non-nested parens
(#3370) (22.12.0)
- `--skip-string-normalization` / `-S` now prevents docstring prefixes from being
normalized as expected (#3168) (since 22.8.0)
- When using `--skip-magic-trailing-comma` or `-C`, trailing commas are stripped from
subscript expressions with more than 1 element (#3209) (22.8.0)
- Implicitly concatenated strings inside a list, set, or tuple are now wrapped inside
parentheses (#3162) (22.8.0)
- Fix a string merging/split issue when a comment is present in the middle of
implicitly concatenated strings on its own line (#3227) (22.8.0)
- Docstring quotes are no longer moved if it would violate the line length limit
(#3044, #3430) (22.6.0)
- Parentheses around return annotations are now managed (#2990) (22.6.0)
- Remove unnecessary parentheses around awaited objects (#2991) (22.6.0)
- Remove unnecessary parentheses in `with` statements (#2926) (22.6.0)
- Remove trailing newlines after code block open (#3035) (22.6.0)
- Code cell separators `#%%` are now standardised to `# %%` (#2919) (22.3.0)
- Remove unnecessary parentheses from `except` statements (#2939) (22.3.0)
- Remove unnecessary parentheses from tuple unpacking in `for` loops (#2945) (22.3.0)
- Avoid magic-trailing-comma in single-element subscripts (#2942) (22.3.0)
- Fix a crash when a colon line is marked between `# fmt: off` and `# fmt: on` (#3439)

### Preview style
Expand Down
40 changes: 39 additions & 1 deletion docs/the_black_code_style/current_style.md
Expand Up @@ -194,7 +194,45 @@ that in-function vertical whitespace should only be used sparingly.
_Black_ will allow single empty lines inside functions, and single and double empty
lines on module level left by the original editors, except when they're within
parenthesized expressions. Since such expressions are always reformatted to fit minimal
space, this whitespace is lost.
space, this whitespace is lost. The other exception is that it will remove any empty
lines immediately following a statement that introduces a new indentation level.

```python
# in:

def foo():

print("All the newlines above me should be deleted!")


if condition:

print("No newline above me!")

print("There is a newline above me, and that's OK!")


class Point:

x: int
y: int

# out:

def foo():
print("All the newlines above me should be deleted!")


if condition:
print("No newline above me!")

print("There is a newline above me, and that's OK!")


class Point:
x: int
y: int
```

It will also insert proper spacing before and after function definitions. It's one line
before and after inner functions and two lines before and after module-level functions
Expand Down
90 changes: 0 additions & 90 deletions docs/the_black_code_style/future_style.md
Expand Up @@ -62,93 +62,3 @@ plain strings. User-made splits are respected when they do not exceed the line l
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).

### Improved empty line management

1. _Black_ will remove newlines in the beginning of new code blocks, i.e. when the
indentation level is increased. For example:

```python
def my_func():

print("The line above me will be deleted!")
```

will be changed to:

```python
def my_func():
print("The line above me will be deleted!")
```

This new feature will be applied to **all code blocks**: `def`, `class`, `if`,
`for`, `while`, `with`, `case` and `match`.

2. _Black_ will enforce empty lines before classes and functions with leading comments.
For example:

```python
some_var = 1
# Leading sticky comment
def my_func():
...
```

will be changed to:

```python
some_var = 1


# Leading sticky comment
def my_func():
...
```

### Improved parentheses management

_Black_ will format parentheses around return annotations similarly to other sets of
parentheses. For example:

```python
def foo() -> (int):
...

def foo() -> looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong:
...
```

will be changed to:

```python
def foo() -> int:
...


def foo() -> (
looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong
):
...
```

And, extra parentheses in `await` expressions and `with` statements are removed. For
example:

```python
with ((open("bla.txt")) as f, open("x")):
...

async def main():
await (asyncio.sleep(1))
```

will be changed to:

```python
with open("bla.txt") as f, open("x"):
...


async def main():
await asyncio.sleep(1)
```
9 changes: 3 additions & 6 deletions src/black/__init__.py
Expand Up @@ -925,9 +925,6 @@ def format_file_contents(src_contents: str, *, fast: bool, mode: Mode) -> FileCo
valid by calling :func:`assert_equivalent` and :func:`assert_stable` on it.
`mode` is passed to :func:`format_str`.
"""
if not mode.preview and not src_contents.strip():
raise NothingChanged

if mode.is_ipynb:
dst_contents = format_ipynb_string(src_contents, fast=fast, mode=mode)
else:
Expand Down Expand Up @@ -1022,7 +1019,7 @@ def format_ipynb_string(src_contents: str, *, fast: bool, mode: Mode) -> FileCon
Operate cell-by-cell, only on code cells, only for Python notebooks.
If the ``.ipynb`` originally had a trailing newline, it'll be preserved.
"""
if mode.preview and not src_contents:
if not src_contents:
raise NothingChanged

trailing_newline = src_contents[-1] == "\n"
Expand Down Expand Up @@ -1101,7 +1098,7 @@ def _format_str_once(src_contents: str, *, mode: Mode) -> str:
for feature in {Feature.PARENTHESIZED_CONTEXT_MANAGERS}
if supports_feature(versions, feature)
}
normalize_fmt_off(src_node, preview=mode.preview)
normalize_fmt_off(src_node)
lines = LineGenerator(mode=mode, features=context_manager_features)
elt = EmptyLineTracker(mode=mode)
split_line_features = {
Expand All @@ -1122,7 +1119,7 @@ def _format_str_once(src_contents: str, *, mode: Mode) -> str:
dst_contents = []
for block in dst_blocks:
dst_contents.extend(block.all_lines())
if mode.preview and not dst_contents:
if not dst_contents:
# Use decode_bytes to retrieve the correct source newline (CRLF or LF),
# and check if normalized_content has more than one line
normalized_content, _, newline = decode_bytes(src_contents.encode("utf-8"))
Expand Down

0 comments on commit c4bd2e3

Please sign in to comment.