From 3d8dd06423bc5a9fba82bc0e8cb369363cadfabf Mon Sep 17 00:00:00 2001 From: chuenchen309 <48723787+chuenchen309@users.noreply.github.com> Date: Thu, 16 Jul 2026 23:13:18 +0800 Subject: [PATCH] Fix --write-changes silently not fixing a trailing-apostrophe typo The word regex admits a trailing apostrophe, so word can end in one. A \b after that can never hold -- it needs a word/non-word transition and the apostrophe is already non-word -- so re.sub matched nothing while codespell still reported FIXED and exited 0. Use lookarounds instead, and escape the interpolated word. Co-Authored-By: Claude Opus 4.8 --- codespell_lib/_codespell.py | 7 ++++++- codespell_lib/tests/test_basic.py | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/codespell_lib/_codespell.py b/codespell_lib/_codespell.py index 994c5c4a66..bb3377e908 100644 --- a/codespell_lib/_codespell.py +++ b/codespell_lib/_codespell.py @@ -1094,7 +1094,12 @@ def parse_lines( if options.write_changes and fix: changed = True - lines[i] = re.sub(rf"\b{word}\b", fixword, lines[i]) + # Not \b: the word regex admits a trailing apostrophe, and a + # \b after one can never hold, so the substitution silently + # matched nothing. + lines[i] = re.sub( + rf"(? None: + """A misspelling ending in an apostrophe must actually be written out.""" + fname = tmp_path / "trailing_apostrophe" + + fname.write_text("dont' go\n", encoding="utf-8") # U+0027 + cs.main("-w", fname, count=False) + assert fname.read_text(encoding="utf-8") == "don't go\n" + + fname.write_text("dont’ go\n", encoding="utf-8") # U+2019 # noqa: RUF001 + cs.main("-w", fname, count=False) + assert fname.read_text(encoding="utf-8") == "don’t go\n" # noqa: RUF001 + + def test_bad_glob( tmp_path: Path, capsys: pytest.CaptureFixture[str],