# ruff F632: 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: F632 (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 F632 explicitly rewrites identity comparisons (`is`) against literals to value comparisons (`==`) because `is` checks object identity, which is unreliable for literals. The observed change—removal of the SyntaxWarning and the program printing 'interned'—is exactly the semantic change the rule documents as its purpose. The program's behavior changes from a warning and no output to no warning and output, which is the intended fix.
- Program: minimized from 9 to 3 lines

## Reproducer

```python
x = 'hello'
if x is 'hello':
  print('interned')
```

## Commands

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

## Observed

```
stderr before: /w/prog.py:2: SyntaxWarning: "is" with 'str' literal. Did you mean "=="?
stderr after: (none)
```

## Diff applied by the fix

```diff
--- orig.py	2026-10-22 13:34:22.951955804 -0400
+++ fixed.py	2026-10-22 13:34:25.030990839 -0400
@@ -1,3 +1,3 @@
 x = 'hello'
-if x is 'hello':
+if x == 'hello':
   print('interned')
```

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

The original uses `is` to test object identity; due to string interning in CPython, `'hello'` may be reused so `x is 'hello'` can evaluate True. Replacing it with `==` changes the check from identity to value equality—while both often yield True for identical literals, they differ when strings are constructed separately or via non-interning operations, making the transformation unsafe as it alters semantic intent.

## Upstream search

Queries: "F632 fix", "F632 identity comparison string literals", "Ruff rule F632 is vs equals strings", "Fix identity check to equality string"

- related: https://github.com/astral-sh/ruff/issues/12518
  Same rule F632 but a different construct: the fix incorrectly rewrites `False == 0` (bool-int comparison) instead of a string literal comparison.
- related: https://github.com/astral-sh/ruff/issues/11736
  Same rule F632 but a different cause: the fix panics on malformed source (`0.0is 64`) rather than rewriting a valid string `is` comparison.
- related: https://github.com/astral-sh/ruff/issues/9374
  Same rule F632 but a different defect: an infinite loop toggling between `==` and `is` on a chained comparison, not a simple string literal.
- related: https://github.com/astral-sh/ruff/issues/8589
  Same rule F632 but a different construct: requests catching `variable is []` (list literal) instead of a string literal.
- related: https://github.com/astral-sh/ruff/issues/6891
  Same rule F632 but a different defect: infinite loop between E712 and F632 on bytes join, not a string `is` comparison.
- related: https://github.com/astral-sh/ruff/issues/1057
  Same rule F632 but a different cause: fix fails to extract CST on `value % 2 is 0` (int modulo), not a string literal.
- related: https://github.com/astral-sh/ruff/issues/4560
  Same rule F632/E712 but a different construct: fix incorrectly rewrites `triggered == False` (bool comparison) instead of a string literal.

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

- [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] Isort rule misses unsorted imports when using user-level ruff.toml file on windows — https://github.com/astral-sh/ruff/issues/19646
- [github, closed] [Feature Idea] Add column headers to `ruff check --statistics`, to avoid ambiguity — https://github.com/astral-sh/ruff/issues/13717
- [github, closed] F632 suggestion leads to false positive when comparing False == 0 — https://github.com/astral-sh/ruff/issues/12518
- [github, closed] Rule F632 cause panic — https://github.com/astral-sh/ruff/issues/11736
- [github, closed] [QA] Should Ruff be able to fix indentation errors (E999) ? — https://github.com/astral-sh/ruff/issues/11846
- [github, closed] Infinite loop in F632/E711 — https://github.com/astral-sh/ruff/issues/9374
- [github, closed] Catch `variable is []` — https://github.com/astral-sh/ruff/issues/8589
- [github, closed] Rules E712,F632 causes infinite loop — https://github.com/astral-sh/ruff/issues/6891
- [tavily] [bug] ruff chokes when fixing invalid comparison (`F632`) · Issue #1057 · astral-sh/ruff · GitHub — https://github.com/astral-sh/ruff/issues/1057
- [tavily] D205 not fixable · Issue #1672 · astral-sh/ruff · GitHub — https://github.com/astral-sh/ruff/issues/1672
- [tavily] Multi-root workspace makes Ruff use wrong settings · Issue #925 · astral-sh/ruff-vscode · GitHub — https://github.com/astral-sh/ruff-vscode/issues/925
- [github, open] Feature: Port Sonar's Python scanner checks — https://github.com/astral-sh/ruff/issues/4935
- [tavily] Fix (E712) changing `==`/`!=` to `is`/`is not` is not correct for some types · Issue #4560 · astral-sh/ruff · GitHub — https://github.com/astral-sh/ruff/issues/4560

</details>
