fixhunt

ruff TC005: fix changes program behavior

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

Hypothesis Nemotron 3 Super predicted to fire fired 1×

keyword-only, positional-only, *args/**kwargs forwarding, defaults evaluated once

Program

before
1def f(pos, /, kw=None, *args, **kwargs):
2 if TYPE_CHECKING:
3 pass
4print(f(1, kw=2, extra=3))
after
1def f(pos, /, kw=None, *args, **kwargs):
2 pass
3print(f(1, kw=2, extra=3))

Output

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

Judge Nemotron 3 Ultra advisory real · high

The fix replaces the TYPE_CHECKING conditional block with an unconditional 'pass' statement, which changes the function's behavior from raising a NameError (when TYPE_CHECKING is undefined) to silently doing nothing. The documentation presents this rewrite as equivalent removal of dead code, but TYPE_CHECKING is not a built-in constant and the rule does not guard against its absence, making the fix unsafe for code that lacks the typing import.

Explanation Nemotron 3 Super unverified

The original function contains a conditional block that raises a NameError when executed because `TYPE_CHECKING` is undefined; this error prevents the `print` statement from running. The rewrite removes the condition and replaces it with an unconditional `pass`, allowing execution to proceed to the `print` call, which outputs `None`. Thus, the behavior changes from an error-induced crash to successful execution with output. This alters the program’s observable outcome, so the transformation is not semantics-preserving despite being labeled safe.

Reproduce

file
prog.py (the before program)
minimized program
r1-p008.py
evidence sheet
r1-p008.md
regression fixture
r1-p008.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 · TC005 function parameter slash · ruff linting conditional block removal · Oracle behavior type checking guard

Details

program
Keyword-only, positional-only, *args/**kwargs forwarding with defaults
hazard
keyword-only, positional-only, *args/**kwargs forwarding, defaults evaluated once
oracle
stdout before: stdout after: None 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
1def f(pos, /, kw=None, *args, **kwargs):
2 if TYPE_CHECKING:
3 pass
4 return pos, kw, args, kwargs
5print(f(1, kw=2, extra=3))
--- orig.py	2026-10-17 16:39:44.636897831 -0400
+++ fixed.py	2026-10-17 16:39:45.025915003 -0400
@@ -1,5 +1,3 @@
 def f(pos, /, kw=None, *args, **kwargs):
-    if TYPE_CHECKING:
-        pass
     return pos, kw, args, kwargs
 print(f(1, kw=2, extra=3))
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)