Skip to content

Keep repeated unchanged lines outside selected ranges - #5436

Merged
cobaltt7 merged 6 commits into
psf:mainfrom
kokokoXUY:fix/anchor-repeated-line-ranges
Oct 5, 2026
Merged

cobaltt7 merged 6 commits into
psf:mainfrom
kokokoXUY:fix/anchor-repeated-line-ranges

Conversation

@kokokoXUY

@kokokoXUY kokokoXUY commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

Description

Related to #4052 and #4033. When unchanged lines have identical text on both sides of a selected range, SequenceMatcher can align those lines at the wrong positions. Formatting lines 2–3 in a five-line example then formats line 5 as well. This anchors identical prefix and suffix lines before diffing the middle, so the second pass keeps the selected range at its original position. The existing regression fixture now expects only the selected lines to change. For disjoint ranges, when the first pass preserves line count and every unselected line is byte-for-byte unchanged, the original ranges can be reused without an ambiguous text diff.

The new regression also covers disjoint ranges selecting lines 1 and 3 of three identical unformatted lines; line 2 now stays untouched. The --line-ranges stability check remains disabled, and this is not a complete replacement for #4052's diff algorithm, so the existing documentation warning remains in place.

Tests: 45 focused tests passed; Black formatting and all pre-commit hooks for changed files passed. The initial full Windows tox -e py313 -- -n 0 run had 505 passes and three failures: two color-diff tests also fail on the unmodified base in this environment, and the third was the old fixture expectation updated in this PR. After that update, the non-Jupyter suite passed 507 selected tests with one skip; two baseline-failing color tests were excluded, and one color-control test excluded by the name filter passed separately. The optional Jupyter stage passed 75 tests. This change was prepared with Codex assistance; the diff and test results were checked before submission.

Checklist - did you ...

  • Follow the stability policy? This changes line selection, not Black's formatting style.
  • Add an entry in CHANGES.md? Added under Unreleased in commit 805d74c.
  • Add / update tests?
  • Add new / update outdated documentation?

Disclosure: this change was prepared with an AI coding assistant (DeepSeek) under my direction; I reviewed the diff and the commands above before pushing.

@cobaltt7

cobaltt7 commented Oct 3, 2026 •

Copy link
Copy Markdown
Collaborator

Could you address/respond to my comment #4052 (comment) as well? I'm not sure I fully understand this function.

@github-actions

github-actions Bot commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

diff-shades results comparing this PR (6286b15) to main (77c0cae):

--preview style: no changes

--stable style: no changes


What is this? | Workflow run | diff-shades documentation

@kokokoXUY

Copy link
Copy Markdown
Contributor Author

Re #4052 (comment) - I measured the three examples end to end with the CLI on main (1ed66a8), on this branch rebased onto it, and on #5484, and replied in full on the issue: #4052 (comment)

Short version, since they turn out to be two defects in _calculate_lines_mappings:

  • Issue example 1 (3-line signature, --line-ranges=1-3): not fixed here - on main and on this branch both unselected print calls get formatted as well. The region before the first matching block was recorded as an unchanged block, so the range was shifted by offset instead of expanded to the changed block, and the diff compared lines verbatim, so the re-indentation done by the first pass made every line look modified. Fix line-range mapping for a changed start of fileΒ #5484 addresses that: the mapping becomes [(1, 1)] and only the signature is joined.
  • Issue example 2 (five identical print ( "format me" ) lines, --line-ranges=2-3): fixed by this PR - main also formats line 5, here only lines 2-3 change.
  • Issue example 3 (def my_func, --line-ranges=2-2): the internal mapping changes with Fix line-range mapping for a changed start of fileΒ #5484 ([(2, 2)] -> [(1, 5)]) but the formatted output is byte-identical on main, this branch and Fix line-range mapping for a changed start of fileΒ #5484, so there is no user-visible difference to fix.

Two process notes: I rebased this branch onto the current main and force-pushed, so the PR should no longer report as dirty and the workflow runs need a re-run. And neither this PR nor #5484 re-enables the --safe stability check that #4034 disabled - they only keep the second pass inside the requested range.

@cobaltt7 cobaltt7 linked an issue Oct 5, 2026 that may be closed by this pull request
@cobaltt7
cobaltt7 merged commit 6e94088 into psf:main Oct 5, 2026
58 checks passed
@cobaltt7

cobaltt7 commented Oct 5, 2026

Copy link
Copy Markdown
Collaborator

Thanks!

luketainton pushed a commit to luketainton/luke_instant-msg-api that referenced this pull request Oct 10, 2026
This PR contains the following updates:

| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [black](https://github.com/psf/black) ([changelog](https://github.com/psf/black/blob/main/CHANGES.md)) | `<26.10.1,>=26.10.0` β†’ `<26.10.2,>=26.10.1` | ![age](https://developer.mend.io/api/mc/badges/age/pypi/black/26.10.1?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/black/26.10.0/26.10.1?slim=true) |

---

### Release Notes

<details>
<summary>psf/black (black)</summary>

### [`v26.10.1`](https://github.com/psf/black/blob/HEAD/CHANGES.md#Version-26101)

[Compare Source](psf/black@26.10.0...26.10.1)

##### Highlights

This release fixes a security issue in Black's bundled GitHub Action. Repositories that
use the action are encouraged to update to the latest version of Black immediately. This
update is received automatically when using `psf/black@stable`, and is independent of
the version of Black installed by the action.

When the GitHub Action reads version specifiers from `tool.black.required-version`, it
now only accepts released versions of Black, as it already did for `black` requirements
in dependency lists. Other values, such as URL references, are now rejected. This issue
has been registered as `GHSA-cg8m-r9f2-5wm2`; a CVE identifier is pending.

##### Stable style

- Fix a long Jupyter notebook assignment magic (for example `x = !ls -la`) being wrapped
  in parentheses, which IPython can no longer run; such cells are now left unchanged
  ([#&#8203;5481](psf/black#5481))
- Keep repeated lines outside the selected `--line-ranges` unchanged ([#&#8203;5436](psf/black#5436))
- Fix `--line-ranges` formatting lines that follow a statement when formatting joins or
  re-indents that statement ([#&#8203;5484](psf/black#5484))
- Fix `--line-ranges` crashing with an internal error when an unselected statement has a
  `# fmt: skip` comment on the last line before a closing bracket ([#&#8203;5477](psf/black#5477))
- Prevent moving an encoding declaration (for example `# -*- coding: latin-1 -*-`) onto
  the first two lines of a file ([#&#8203;5487](psf/black#5487))
- Fix adding an extra trailing blank line inside a multi-line module docstring when its
  last line is near the line length limit ([#&#8203;5494](psf/black#5494))

##### Preview style

- Do not split short expressions on delimiters (such as binary operators, comparisons,
  or comprehensions) inside brackets when preceded by a standalone comment ([#&#8203;5455](psf/black#5455))
- Fix the unstable `string_processing` feature removing backslash-newline sequences from
  raw strings, which changed their value ([#&#8203;5482](psf/black#5482))
- Avoid adding unnecessary parentheses around unbreakable right-hand side expressions in
  assignments (such as annotated assignments or subscript targets) ([#&#8203;5473](psf/black#5473))
- Parenthesize expressions with parameter comments when they exceed the line length
  under `--preview` ([#&#8203;5442](psf/black#5442))
- Fix `wrap_long_dict_values_in_parens` dropping the parentheses around a right-hand
  side that contains a dictionary, leaving a line over the length limit ([#&#8203;5492](psf/black#5492))
- Fix the unstable `string_processing` feature adding a space after `*` or `**` in a PEP
  695 type parameter (`* Ts = ...`) when it splits a string in the parameter's default
  ([#&#8203;5504](psf/black#5504))
- Avoid unnecessary line splits of trailers (such as indexing/subscripts) when an
  earlier bracket split exceeds the line length only due to a trailing comment ([#&#8203;5498](psf/black#5498))

##### Configuration

- Add `--cache-dir` to configure the cache directory from the command line ([#&#8203;5433](psf/black#5433))
- Don't cache a file as formatted after formatting or checking it with `--line-ranges`,
  which made a later full `black --check` pass and `black` skip the unformatted lines
  ([#&#8203;5476](psf/black#5476))
- Respect a `.gitignore` that starts with a UTF-8 byte order mark. The mark became part
  of the first pattern, so that pattern never matched and Black formatted files that git
  ignores ([#&#8203;5497](psf/black#5497))

##### Performance

- Avoid quadratic runtime when splitting very long lines with many trailing bracket
  pairs (such as consecutive subscripts) ([#&#8203;5475](psf/black#5475))

##### Integrations

- Fix the GitHub Action crashing on dependency-group includes when `use_pyproject` is
  enabled ([#&#8203;5479](psf/black#5479))
- When the GitHub Action reads version specifiers from `tool.black.required-version`, it
  now only accepts released versions of Black, as it already did for `black`
  requirements in dependency lists. Other values, such as URL references, are now
  rejected. ([#&#8203;5510](psf/black#5510))

</details>

---

### Configuration

πŸ“… **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

β™» **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate CLI](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xNDkuMCIsInVwZGF0ZWRJblZlciI6IjQ0LjE0OS4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJ0eXBlL2RlcGVuZGVuY2llcyJdfQ==-->

Reviewed-on: https://git.tainton.uk/luke/instant-msg-api/pulls/292
Co-authored-by: renovate[bot] <renovate-bot@git.tainton.uk>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve adjusted_lines's diff algorithm used in --line-ranges.

2 participants