Stable style
--line-rangesno longer inserts an empty line after a docstring when the range
covers only the docstring itself (#5312)- Fix
# fmt: skipon a bracketed ternary turning the surrounding tuple into a call
(#5464) - Fix crash when
# fmt: skipis placed on a one-line function or class with PEP 695
type parameters (#5429) - Fix an inline comment after the closing bracket of optional parentheses being moved
inside the parentheses when the parenthesized expression contains own-line comments
(#5395) - Fix unparseable output when
# fmt: skipis placed on a bracket of anif,while,
for, orwithheader (#5401, #5405) - Fix crash when formatting parenthesized expressions with multiple inline comments and
# fmt: skip(#5414) - Fix parsing Jupyter notebook assignment magics when non-ASCII characters appear
earlier on the line (#5381) - Preserve blank lines that come immediately before a
# fmt: oncomment (#5300) - Keep the parentheses around the target of an annotated assignment (e.g.
(x): int = 5), which prevent CPython from including the name in__annotations__
(#5321) - Stop treating a t-string in docstring position as a docstring (e.g.
t" spam "as
the first statement of a module, class or function) (#5287) - Fix unparseable output for a t-string whose replacement field contains a quote (e.g.
t'\'{a["b"]}\'') (#5265) - Fix unparseable output for a triple-quoted string whose body ends in an
already-escaped double quote (e.g.'''\'''\"''') (#5262) - Fix
--skip-magic-trailing-commadropping the trailing comma from a split
single-element tuple used as a lambda parameter default (#5246) - Fix unstable formatting when an inline comment sits on optional parentheses (e.g. a
parenthesized assert message) (#5241) - Fix
--skip-magic-trailing-commadropping the trailing comma of a one-element
subscript (a[x,]) when the line is long enough to be split and contains a power
operator (#5272) - Fix crash when a standalone comment sits between tokens of a comprehension or lambda
(#5144) - Fix inline comments on a bracket inside a comprehension being dropped (#5330)
- Respect the magic trailing comma in a PEP 695 type parameter list containing a
*TypeVarTupleor**ParamSpec(#5244) - Fix crash when a comment-only
# fmt: off/# fmt: onblock is followed by awith
statement after another standalone comment (#5189) - Fix a crash when splitting
case case if ...match patterns at very small line
lengths (#5147) - Fix multiline docstring indentation when leading tabs are used inside indented
docstrings (#5148) - Respect
# fmt: skipon a line that opens a bracket (e.g.
from x import ( # fmt: skip) when a standalone comment is among the bracket's
contents (#5161) - Fix an AST safety error when separate
# type: ignorecomments in a parenthesized
attribute chain were merged onto one physical line (#5297) - Preserve comments and blank lines outside requested ranges when formatting with
--line-ranges(#5175) - Fix crash when
# fmt: skipis used on one-lineasync def,async with, and
async forstatements containing a semicolon (#5311) - Stop converting form feeds or other similar characters in docstrings into newlines
(#5461) - Fix
--skip-source-first-lineturning the skipped line's CRLF ending into\r\r\n
when reformatting a file with CRLF line endings (#5438)
Preview style
New preview features
- Add missing blank lines after classes whose last method has an ellipsis body (#5439)
- Split only the brackets holding a magic trailing comma when more trailers follow them
(e.g. stop splitting inside the[2]of[1,][2](3)) (#5448) - Keep dictionary keys containing operators together on one line when the value can be
wrapped onto a new line instead (#5435) - Remove redundant parentheses around individual variables in unpacking targets (e.g.
for (x), (y) in points:becomesfor x, y in points:) (#5416) - Normalize uppercase
Tprefixes on t-strings to lowercase (#5425) - Remove redundant parentheses around generator expressions (#5304, #5369)
- Preserve two blank lines before a top-level class starting inside a
# fmt: offblock
after an import (#5238) - Fix unnecessary parentheses around short right-hand expressions in indexed assignments
(e.g.x[key] = expr) (#5095) - Parenthesize tuple expressions in
yieldstatements for consistency with function
calls and returns (#5170) - Stop splitting between a variable and its operator (
not in,==,is, ...) when
the right-hand side is a bracketed expression, and instead split inside the brackets
(#5135) - In
.pyistub files, enforce a blank line after a function or method that has a
docstring-only body when another comment or statement follows it (#5158)
Updates to existing preview features
- Fix crash in stub files when
# fmt: skipis placed on a function in a group of
same-name decorated functions (e.g.@overloads or a property setter) (#5430) - Keep the parentheses around a lambda used as the iterable of a comprehension (e.g.
[x for x in (lambda: 0) if x]) (#5176, #5200)
Updates to existing unstable features
- Do not treat multi-line expressions with merged strings and trailing
# type: ignore
comments as single-line unsplittable expressions (#5466) - Fix duplicated inline comment when stripping the parentheses around a string or
merging a backslash-continued string on the same line (#5449) - Split long stringified return annotations even when the function has parameters
(#5427) - Don't hug brackets when doing so would join two
# type: ignorecomments onto one
line (#5271) - Fix a crash when
# type: ignoreis lost during formatting of a long parenthesized
string (#5329) - Fix only the first part of an implicitly concatenated unmergeable string (e.g.
r"..." r"...") being wrapped in parentheses (#5434)
Configuration
- Add support for
NO_COLORenvironment variable to disable ANSI output (#5129) - Remove spurious target version warning when runtime version is included in a
--target-versionflag (#5167) - Fix
--force-excludenot excluding files whose path contains..(e.g.
black ../generated/file.pyrun from a subdirectory) (#5471) - Fall back to the default configuration, with a warning, when the given sources share
no common project root (e.g. they are on different drives on Windows) instead of
crashing (#5386) - Fix loading a stale cached
pyproject.tomlpath when--codeis used from different
working directories in the same process (#5152) - Add validation for
--line-rangesvalues (#5107) - Ignore empty cache files instead of raising an
EOFError(#5192) - Reject non-string
includeandforce-excludevalues inpyproject.toml(#5193) - Validate
BLACK_NUM_WORKERSvalues and report invalid values as usage errors instead
of crashing (#5211) - Ignore permission errors when reading cache (#5258)
Packaging
- Reduce the size of Linux standalone binaries by stripping debug symbols during the
PyInstaller release build (#5223) - Black is now released using GitHub
Immutable Releases
(#5296)
Performance
- Fix superlinear runtime growth with the number of input files (#5450)
- Improve performance on strings containing many consecutive backslashes (#5163)
- Improve performance on files with many
# fmt: skip/# fmt: off/# fmt: oncomments
(#5169, #5190, #5232) - Improve performance on long calls and collections (#5177)
- Improve performance on multiline strings inside large collections (e.g. a dict literal
with triple-quoted strings as values) (#5188) - Improve performance on files with many soft keywords (e.g.
match/caseblocks)
(#5186) - Improve performance on long semicolon-separated statements (in the stable style) and
large dict literals (in--preview) (#5184) - Improve performance of
--line-rangeson files with many sibling blocks (a long
if/elifchain, amatchwith many cases, or many top-level definitions) (#5213) - Improve performance on deeply nested bracketed expressions (#5171, #5242)
- Improve performance on lists and subscripts holding one long expression without
operators (e.g. a long run of implicitly concatenated strings inside[]) (#5239) - Improve performance on deeply chained operations (e.g. a long
a ** b ** c ** ...
chain) (#5235) - Improve performance on long
if/elifchains and other compound statements with many
clauses (#5322) - Improve performance of
string_processing:
Output
- Report parser failures using editor-friendly
path:line:columnlocations (#5237) - Fix crash when writing formatted code or diffs to a
sys.stdoutthat has nobuffer
attribute (e.g. in Jupyter notebooks) (#5411) - Report parse failures on Black's own output as internal errors (#5383)
Blackd
- Return HTTP 400 instead of 500 when the
X-Python-Variantheader is empty or has an
empty entry (e.g. a trailing comma) (#5428) - Allow optional whitespace around comma-separated versions and
pyiin the
X-Python-Variantheader (#5441)
Integrations
- Remove unused
migrate-blackscript (#5319) - Support PEP 440 version specifiers in
tool.black.required-versionfor the GitHub
Action (#5399) - Add outputs (
is_formatted,change_count,same_count,failure_count) to GitHub
Action runs (#5408)
Documentation
- Document
vim-python-pep8-indent, which provides anindentexprfor Black-style
insert-mode indentation (#5288)