# ruff W605: fix changes program behavior

Internal evidence sheet generated by fixhunt. Not an issue text. A human re-verifies, checks the duplicates
below, and writes the upstream report in their own words following the project's AI policy.

- Tool: ruff ruff 0.17.1
- Rule: W605 (tool labels the fix: unknown, this fix reported as safe)
- Oracle: fix-changes-behavior
- Judge (Nemotron 3 Ultra, advisory): intended-change, severity low. The rule rewrites an invalid escape sequence '\.' to a raw string r'\.' to eliminate the SyntaxWarning, which is exactly the documented purpose. The stderr difference shows the deprecation warning disappearing, confirming the fix works as intended.
- Program: minimized from 7 to 1 lines

## Reproducer

```python
s = '\.'
```

## Commands

```sh
python3 prog.py
ruff check --preview --isolated --select W605 --fix prog.py
python3 prog.py
```

## Observed

```
stderr before: /w/prog.py:1: SyntaxWarning: invalid escape sequence '\.'
stderr after: (none)
```

## Diff applied by the fix

```diff
--- orig.py	2026-10-22 13:32:33.796118673 -0400
+++ fixed.py	2026-10-22 13:32:36.006155820 -0400
@@ -1 +1 @@
-s = '\.'
+s = r'\.'
```

## Why the rewrite is not equivalent (model draft, verify before use)

The original string literal `'\.'` contains an invalid escape sequence `\.` which Python treats as a literal backslash followed by a dot, but emits a SyntaxWarning because it’s not a recognized escape; the raw string `r'\.'` explicitly treats the backslash as a literal character without interpretation, so while both evaluate to the same two-character string (`\` then `.`), the original triggered a warning during compilation due to the invalid escape, whereas the raw string suppresses it—changing the program’s observable behavior (the warning output) even though the runtime value is identical. Thus, the fix alters semantics by removing a side effect (the warning).

## Upstream search

Queries: "W605 fix", "W605 invalid escape sequence", "backslash dot literal warning", "raw string prefix recommendation"

- related: https://github.com/astral-sh/ruff/issues/11491
  same rule W605 but different construct (f-string vs plain string)
- related: https://github.com/astral-sh/ruff/issues/19655
  W605 fix interaction with ISC002, same rule but different cause
- duplicate: https://github.com/astral-sh/ruff/issues/11461
  same rule W605, same fix (raw string), same defect class (invalid escape sequence in plain string)
- related: https://github.com/astral-sh/ruff/issues/10434
  W605 panic in f-string, same rule but different construct and symptom
- related: https://github.com/astral-sh/ruff/issues/6987
  W605 autofix error with ANN401, same rule but different trigger
- related: https://github.com/astral-sh/ruff/issues/5061
  feature request to use raw strings for W605, same fix strategy but not a defect report
- related: https://github.com/astral-sh/ruff/issues/19543
  W605 on byte strings, same rule but different string type
- related: https://github.com/astral-sh/ruff/issues/12165
  W605 panic on specific file, same rule but different symptom (panic vs wrong fix)
- related: https://github.com/astral-sh/ruff/issues/474
  original W605 implementation issue, same rule but not the same fix defect

<details><summary>All hits</summary>

- [github, open] Wrong fix for W605 in f-strings — https://github.com/astral-sh/ruff/issues/11491
- [github, open] Implement remaining `pycodestyle` rules — https://github.com/astral-sh/ruff/issues/2402
- [github, open] Include some of the checks from flake8-literal — https://github.com/astral-sh/ruff/issues/8616
- [github, closed] unused-function-argument not silenced by prefixed underscore if variable name is "次" — https://github.com/astral-sh/ruff/issues/28721
- [github, open] Implement Pylint — https://github.com/astral-sh/ruff/issues/970
- [github, closed] ISC002 makes W605 unfixable on playground — https://github.com/astral-sh/ruff/issues/19655
- [github, closed] W605 fix is unsafe — https://github.com/astral-sh/ruff/issues/11461
- [github, closed] Ruff does not clean up unused import if it has same name like object attribute — https://github.com/astral-sh/ruff/issues/12775
- [github, closed] Pack of fuzzer Autofix/Infinite loop errors [2] — https://github.com/astral-sh/ruff/issues/8402
- [github, closed] Rule W605 cause panic — https://github.com/astral-sh/ruff/issues/10434
- [tavily] Rules ANN401,W605 cause autofix error · Issue #6987 · astral-sh/ruff · GitHub — https://github.com/astral-sh/ruff/issues/6987
- [tavily] Change W605 autofix to use raw strings if possible · Issue #5061 · astral-sh/ruff · GitHub — https://github.com/astral-sh/ruff/issues/5061
- [github, open] Should W605 flag certain byte string escapes? — https://github.com/astral-sh/ruff/issues/19543
- [github, open] Rule suggestion: Emit warning for continuation characters in multi-line strings — https://github.com/astral-sh/ruff/issues/7359
- [github, open] Ruff should warn on all CPython SyntaxWarnings — https://github.com/astral-sh/ruff/issues/20196
- [github, open] Validation for ruff config file — https://github.com/astral-sh/ruff/issues/10487
- [github, closed] Checking file with rule W605 cause panic — https://github.com/astral-sh/ruff/issues/12165
- [tavily] Implement W605, invalid escape sequence · Issue #474 · astral-sh/ruff · GitHub — https://github.com/astral-sh/ruff/issues/474
- [tavily] Ruleset Suggestion: wemake-python-styleguide · Issue #3845 · astral-sh/ruff · GitHub — https://github.com/astral-sh/ruff/issues/3845
- [tavily] Feature: Port Sonar's Python scanner checks · Issue #4935 · astral-sh/ruff · GitHub — https://github.com/astral-sh/ruff/issues/4935

</details>
