ruff TC005: fix changes program behavior
Hypothesis Nemotron 3 Super predicted to fire fired 1×
evaluation order and side effects when expressions are merged, duplicated or deleted
Program
Output
(no stdout) NameError: name 'TYPE_CHECKING' is not defined
(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
- duplicate astral-sh/ruff/issues/28868 same TC005 empty-type-checking-block fixer removing an if TYPE_CHECKING: pass block
- related astral-sh/ruff/issues/15681 TC003/TC002/TC001 false positives on manual TYPE_CHECKING with future annotations
- related astral-sh/ruff/issues/1785 feature request to implement flake8-type-checking rules
- related astral-sh/ruff/issues/2214 TCH rules requiring future annotations for TYPE_CHECKING
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
--- 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)