Visitar URL original
Prepare release 26.10.0 by JelleZijlstra · Pull Request #5478 · psf/black · GitHub
Skip to content

Prepare release 26.10.0 - #5478

Merged
cobaltt7 merged 6 commits into
mainfrom
ci/prepare-release/26.10.0
Oct 4, 2026
Merged

cobaltt7 merged 6 commits into
mainfrom
ci/prepare-release/26.10.0

Conversation

@JelleZijlstra

@JelleZijlstra JelleZijlstra commented Oct 3, 2026 •

Copy link
Copy Markdown
Collaborator

Please follow the process in the docs to cut a release.

Changelog Diff
diff --git a/CHANGES.md b/CHANGES.md
index b710349a..1ae1b599 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,5 +1,196 @@
 # Change Log
 
+## Version 26.10.0
+
+### Stable style
+
+- `--line-ranges` no longer inserts an empty line after a docstring when the range
+  covers only the docstring itself (#5312)
+- Fix `# fmt: skip` on a bracketed ternary turning the surrounding tuple into a call
+  (#5464)
+- Fix crash when `# fmt: skip` is 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: skip` is placed on a bracket of an `if`, `while`,
+  `for`, or `with` header (#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: on` comment (#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-comma` dropping 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-comma` dropping 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
+  `*TypeVarTuple` or `**ParamSpec` (#5244)
+- Fix crash when a comment-only `# fmt: off`/`# fmt: on` block is followed by a `with`
+  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: skip` on 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: ignore` comments 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: skip` is used on one-line `async def`, `async with`, and
+  `async for` statements containing a semicolon (#5311)
+- Stop converting form feeds or other similar characters in docstrings into newlines
+  (#5461)
+- Fix `--skip-source-first-line` turning 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:` becomes `for x, y in points:`) (#5416)
+- Normalize uppercase `T` prefixes 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: off` block
+  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 `yield` statements 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 `.pyi` stub 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: skip` is placed on a function in a group of
+  same-name decorated functions (e.g. `@overload`s 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: ignore` comments onto one
+  line (#5271)
+- Fix a crash when `# type: ignore` is 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_COLOR` environment variable to disable ANSI output (#5129)
+- Remove spurious target version warning when runtime version is included in a
+  `--target-version` flag (#5167)
+- Fix `--force-exclude` not excluding files whose path contains `..` (e.g.
+  `black ../generated/file.py` run 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.toml` path when `--code` is used from different
+  working directories in the same process (#5152)
+- Add validation for `--line-ranges` values (#5107)
+- Ignore empty cache files instead of raising an `EOFError` (#5192)
+- Reject non-string `include` and `force-exclude` values in `pyproject.toml` (#5193)
+- Validate `BLACK_NUM_WORKERS` values 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](https://docs.github.com/code-security/concepts/supply-chain-security/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: on` comments
+  (#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`/`case` blocks)
+  (#5186)
+- Improve performance on long semicolon-separated statements (in the stable style) and
+  large dict literals (in `--preview`) (#5184)
+- Improve performance of `--line-ranges` on files with many sibling blocks (a long
+  `if`/`elif` chain, a `match` with 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`/`elif` chains and other compound statements with many
+  clauses (#5322)
+- Improve performance of `string_processing`:
+  - when merging implicitly concatenated f-strings containing long string literals
+    (#5165)
+  - when merging long implicitly concatenated strings (#5173, #5194)
+  - when rewriting large nodes (e.g. `"%s ..." % (a, b, c, ...)`) (#5178, #5199, #5220)
+  - when splitting long string literals (#5183)
+
+### Output
+
+- Report parser failures using editor-friendly `path:line:column` locations (#5237)
+- Fix crash when writing formatted code or diffs to a `sys.stdout` that has no `buffer`
+  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-Variant` header is empty or has an
+  empty entry (e.g. a trailing comma) (#5428)
+- Allow optional whitespace around comma-separated versions and `pyi` in the
+  `X-Python-Variant` header (#5441)
+
+### Integrations
+
+- Remove unused `migrate-black` script (#5319)
+- Support PEP 440 version specifiers in `tool.black.required-version` for 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 an `indentexpr` for Black-style
+  insert-mode indentation (#5288)
+
 ## Version 26.5.1
 
 ### Stable style
@@ -186,7 +377,7 @@ The following change was not in any previous stable release:
 
 - Regenerated the `_width_table.py` and added tests for the Khmer language (#4253)
 
-This release alo bumps `pathspec` to v1 and fixes inconsistencies with Git's
+This release also bumps `pathspec` to v1 and fixes inconsistencies with Git's
 `.gitignore` logic (#4958). Now, files will be ignored if a pattern matches them, even
 if the parent directory is directly unignored. For example, Black would previously
 format `exclude/not_this/foo.py` with this `.gitignore`:
@@ -197,7 +388,7 @@ exclude/
 ```
 
 Now, `exclude/not_this/foo.py` will remain ignored. To ensure `exclude/not_this/` and
-all of it's children are included in formatting (and in Git), use this `.gitignore`:
+all of its children are included in formatting (and in Git), use this `.gitignore`:
 
 ```
 */exclude/*
@@ -428,8 +619,8 @@ The following changes were not in any previous release:
 
 ### Preview style
 
-- Fix type annotation spacing between * and more complex type variable tuple (i.e. `def
-  fn(*args: *tuple[*Ts, T]) -> None: pass`) (#4440)
+- Fix type annotation spacing between * and more complex type variable tuple (i.e.
+  `def fn(*args: *tuple[*Ts, T]) -> None: pass`) (#4440)
 
 ### Caching
 
This PR is automated

@JelleZijlstra JelleZijlstra added ci: skip news Pull requests that don't need a changelog entry. C: maintenance Related to project maintenance, e.g. CI, testing, policy changes, releases labels Oct 3, 2026
…elease/26.10.0

Signed-off-by: cobalt <61329810+cobaltt7@users.noreply.github.com>
@cobaltt7

cobaltt7 commented Oct 4, 2026 •

Copy link
Copy Markdown
Collaborator

In addition to copyediting the changelog, I also included some small follow-ups to #5296, found when using the new system in practice:

  • support (#1234, #1235) in the changelog check script
  • add a note to automated PRs, since they're not easily identifiable now that they use a PAT
  • add a comment not to manually edit the prepare release PR description
  • prevent release.py from removing nested headings in changelog sections
  • show help when running release.py without arguments

The changelog had gotten rather unwieldly, which was my fault - I'll be paying more attention to the placement and wording of changelog entries in future reviews.
Additionally, since this changelog is still quite long, I added subheadings inside the "Preview style" section to distinguish between new and updated preview features, which is probably the most impactful section of the changelog. I don't think it's necessary to include it every time because many changelogs will be shorter. I also don't think any other section would benefit from subheadings; the only other long section is "Stable style", and it's all just small bugfixes.

Will merge in ~11 hours

cobaltt7 and others added 3 commits October 3, 2026 21:50
Signed-off-by: cobalt <61329810+cobaltt7@users.noreply.github.com>
Signed-off-by: cobalt <61329810+cobaltt7@users.noreply.github.com>
@cobaltt7
cobaltt7 merged commit 4f1883b into main Oct 4, 2026
65 checks passed
@cobaltt7
cobaltt7 deleted the ci/prepare-release/26.10.0 branch October 4, 2026 16:46
@n-badtke-cg

n-badtke-cg commented Oct 5, 2026 •

Copy link
Copy Markdown

Just curious: is there a specific reason why jumping from 26.5 -> 26.10? :D

Nevermind, answered by myself, version is based on CalVer, sorry ^^ we are in October 2026 -> 26.10
My mind just defaulted to SemVer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C: maintenance Related to project maintenance, e.g. CI, testing, policy changes, releases ci: skip news Pull requests that don't need a changelog entry.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants