fixhunt

ruff E714: fix changes program behavior

fix-changes-behaviorlabelled safeintrospection-only · lowrelated
Findings / 2026-10-17T20-49-21-682Z-c4qe-ruff-E714 / r1-p007ruff 0.17.15 → 2 lines2026-10-17 20:49 UTC

Hypothesis Nemotron 3 Super predicted to fire fired 1×

bytes vs str, encoding and newline handling, text vs binary modes

Program

before
1b = b'hello'
2print('Bytes check:', not b is b'hello')
after
1b = b'hello'
2print('Bytes check:', b is not b'hello')

Output

stdout beforeexit 0
Bytes check: False
<wd>/prog: SyntaxWarning: "is" with 'bytes' literal. Did you mean "=="?
stdout afterexit 0
Bytes check: False
<wd>/prog: SyntaxWarning: "is not" with 'bytes' literal. Did you mean "!="?
fired
1 before · 0 after
runs
each version twice, same file name, no network

Judge Nemotron 3 Ultra advisory introspection-only · low

The rewrite changes `not b is b'hello'` to `b is not b'hello'`, which is semantically equivalent. The only observed difference is the SyntaxWarning message text, which quotes the source code and therefore changes to reflect the rewritten form (`"is not" with 'bytes' literal` instead of `"is" with 'bytes' literal`). This is pure source-text introspection, not a runtime behavior change.

Explanation Nemotron 3 Super unverified

The original expression `not b is b'hello'` evaluates as `(not b) is b'hello'`, where `not b` yields False (since non-empty bytes are truthy), so it checks whether False is identical to the byte literal—always false. The rewritten form `b is not b'hello'` correctly groups as `b is (not b'hello')`, testing identity between `b` and the negated literal; since `not b'hello'` is also False, this similarly compares `b` to False via identity—but now directly on `b`. Though both yield false here due to interning quirks, the operator precedence change alters evaluation order and meaning generally, making the transformation unsafe for arbitrary values. The warning shift reflects this semantic difference in how Python parses chained identity operations.

Reproduce

file
prog.py (the before program)
minimized program
r1-p007.py
evidence sheet
r1-p007.md
regression fixture
r1-p007.py the minimized program with a header stating the observed change, for the tool's test suite
python3 prog.py
ruff check --preview --isolated --select E714 --fix prog.py
python3 prog.py

Upstream search GitHub issues Tavily Nemotron 3 Super + Ultra

E714 fix · E714 bytes identity comparison · not x is y pattern · SyntaxWarning bytes literal

  • related astral-sh/ruff/issues/4082 E714 complex logic handling with chained 'is' comparisons, same rule but different construct (chained vs negated)
  • related astral-sh/ruff/issues/1237 E711 autofix messes up quotes, same autofix quality problem but different rule (E711 vs E714)

Details

program
Bytes vs str identity
hazard
bytes vs str, encoding and newline handling, text vs binary modes
oracle
stderr before: <wd>/prog: SyntaxWarning: "is" with 'bytes' literal. Did you mean "=="? stderr after: <wd>/prog: SyntaxWarning: "is not" with 'bytes' literal. Did you mean "!="?
run
2026-10-17T20-49-21-682Z-c4qe-ruff-E714
generated program (5 lines) and the fix's diff
1b = b'hello'
2s = 'hello'
3print('Bytes check:', not b is b'hello')
4print('Str check:', not s is 'hello')
5print('Cross-type:', not b is s)
--- orig.py	2026-10-17 16:49:34.829615139 -0400
+++ fixed.py	2026-10-17 16:49:35.016618951 -0400
@@ -1,5 +1,5 @@
 b = b'hello'
 s = 'hello'
-print('Bytes check:', not b is b'hello')
-print('Str check:', not s is 'hello')
-print('Cross-type:', not b is s)
+print('Bytes check:', b is not b'hello')
+print('Str check:', s is not 'hello')
+print('Cross-type:', b is not s)
rule documentation given to the models
# not-is-test (E714)

Derived from the **pycodestyle** linter.

Fix is always available.

## What it does
Checks for identity comparisons using `not {foo} is {bar}`.

## Why is this bad?
According to [PEP8], testing for an object's identity with `is not` is more
readable.

## Example
```python
if not X is Y:
    pass
Z = not X.B is Y
```

Use instead:
```python
if X is not Y:
    pass
Z = X.B is not Y
```

[PEP8]: https://peps.python.org/pep-0008/#programming-recommendations