fixhunt

ruff TC005: fix changes program behavior

fix-changes-behaviorlabelled safereal · highduplicate
Findings / 2026-10-17T20-39-34-299Z-g1ez-ruff-TC005 / r1-p007ruff 0.17.15 → 2 lines2026-10-17 20:39 UTC

Hypothesis Nemotron 3 Super predicted to fire fired 1×

evaluation order and side effects when expressions are merged, duplicated or deleted

Program

before
1if TYPE_CHECKING:
2 pass
after
1(fixed source not recorded; see the unified diff below)

Output

stdout beforeexit 1
(no stdout)
NameError: name 'TYPE_CHECKING' is not defined
stdout afterexit 0
(no stdout)
fired
1 before · 0 after
runs
each version twice, same file name, no network

Judge Nemotron 3 Ultra advisory real · high

The rule removes an `if TYPE_CHECKING:` block without ensuring `TYPE_CHECKING` is imported from `typing`. In the original code, the `NameError` occurs at runtime when evaluating the condition, but the fix deletes the block entirely, silencing the error and changing the exit status from 1 to 0. The documentation presents the rewrite as a safe removal of dead code, but it is only safe when `TYPE_CHECKING` is properly defined; otherwise, it masks a pre-existing runtime failure.

Explanation Nemotron 3 Super unverified

The original program references `TYPE_CHECKING` in a conditional; if undefined, it raises a `NameError`. Removing that block eliminates the reference entirely, so no error occurs when `TYPE_CHECKING` is absent—changing behavior from raising an exception to executing silently. This alters observable outcomes, violating semantic equivalence.

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 TC005 --fix prog.py
python3 prog.py

Upstream search GitHub issues Tavily Nemotron 3 Super + Ultra

TC005 fix · ruff TC005 if TYPE_CHECKING block · TC005 remove unused conditional import guard · fix behavior of empty TYPE_CHECKING blocks

Details

program
Evaluation order and side effects in expression merging
hazard
evaluation order and side effects when expressions are merged, duplicated or deleted
oracle
exit 1 → 0 stderr before: NameError: name 'TYPE_CHECKING' is not defined stderr after: (none)
run
2026-10-17T20-39-34-299Z-g1ez-ruff-TC005
generated program (5 lines) and the fix's diff
1side = 0
2if TYPE_CHECKING:
3 pass
4side += 1
5print(side)
--- orig.py	2026-10-17 16:39:44.154876551 -0400
+++ fixed.py	2026-10-17 16:39:44.537893460 -0400
@@ -1,5 +1,3 @@
 side = 0
-if TYPE_CHECKING:
-    pass
 side += 1
 print(side)
rule documentation given to the models
# empty-type-checking-block (TC005)

Derived from the **flake8-type-checking** linter.

Fix is always available.

## What it does
Checks for an empty type-checking block.

## Why is this bad?
The type-checking block does not do anything and should be removed to avoid
confusion.

## Example
```python
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    pass

print("Hello, world!")
```

Use instead:
```python
print("Hello, world!")
```

## References
- [PEP 563: Runtime annotation resolution and `TYPE_CHECKING`](https://peps.python.org/pep-0563/#runtime-annotation-resolution-and-type-checking)