Change8

26.1.0

Breaking Changes
📦 blackView on GitHub →
2 breaking11 features🐛 4 fixes🔧 2 symbols

Summary

This release introduces the 2026 stable style, bringing numerous formatting improvements and fixes, and updates the underlying ignore logic to precisely match Git's behavior regarding `.gitignore` patterns.

⚠️ Breaking Changes

  • The logic for ignoring files based on `.gitignore` patterns has been updated to match Git's behavior more closely. Previously, if a parent directory was unignored, files within it might still be formatted even if they matched an ignore pattern. Now, files will be ignored if a pattern matches them, even if the parent directory is directly unignored. To ensure a directory and all its children are included (unignored), use a pattern like `!*/directory_name/` instead of just `!directory_name/` if you need to override subdirectory ignores.
  • The behavior of `.gitignore` matching has changed: files will now be ignored if a pattern matches them, even if the parent directory is directly unignored. If you previously relied on unignoring a directory to override nested ignores, you might need to adjust your `.gitignore` file (e.g., by adding `*/` prefixes to include patterns).

Migration Steps

  1. Review your `.gitignore` files if you rely on complex include/exclude logic involving parent directories, as the ignore matching now strictly follows Git's behavior where file matches override directory unignores.
  2. If you need to unignore all children of a directory, ensure your unignore pattern uses a wildcard prefix, e.g., `!*/directory_name/`.

✨ New Features

  • Introduced the 2026 stable style, stabilizing several formatting rules.
  • Implemented `always_one_newline_after_import`: Always force one blank line after import statements, except when the line after the import is a comment or an import statement.
  • Implemented `fix_fmt_skip_in_one_liners`: Fixed `# fmt: skip` behavior on one-liner declarations, preventing incorrect collapsing.
  • Implemented `fix_module_docstring_detection`: Fixed module docstrings being treated as normal strings if preceded by comments.
  • Implemented `fix_type_expansion_split`: Fixed type expansions splitting in generic functions.
  • Implemented `multiline_string_handling`: Made expressions involving multiline strings more compact.
  • Implemented `normalize_cr_newlines`: Added `\r` style newlines to potential newlines to normalize file newlines both from and to.
  • Implemented `remove_parens_around_except_types`: Removed parentheses around multiple exception types in `except` and `except*` without `as`.
  • Implemented `remove_parens_from_assignment_lhs`: Removed unnecessary parentheses from the left-hand side of assignments while preserving magic trailing commas and intentional multiline formatting.
  • Implemented `standardize_type_comments`: Formatted type comments which have zero or more spaces between `#` and `type:` or between `type:` and value to `# type: (value)`.
  • Regenerated the `_width_table.py` and added tests for the Khmer language.

🐛 Bug Fixes

  • Fixed `# fmt: skip` behavior on one-liner declarations where the declaration would have been incorrectly collapsed.
  • Fixed module docstrings being treated as normal strings if preceded by comments.
  • Fixed type expansions splitting in generic functions.
  • Explicitly shut down the multiprocessing manager when run in diff mode.

Affected Symbols