fixhunt

ruff UP047

labelled unknown
Runs / 2026-10-17T21-27-06-200Z-pbn7-ruff-UP047ruff 0.17.12026-10-17 21:27 UTC8 programs × 2 round(s)16 programs, 0 fired, 0 fixed, 0 findings, 0 rejectedmodel cost $0.0038

Analysis Nemotron 3 Super

Flags standalone TypeVar and ParamSpec usage in generic function annotations.

Fix: Removes the standalone TypeVar/ParamSpec variable definitions and adds the corresponding type parameters to the function signature using PEP 695 syntax (e.g., def func[T](x: T) -> T: ...).

12 hazards
  • Rewriting changes the scope of the type variable from module-level to function-local, which can break code that references the variable outside the function (e.g., in other function signatures or class definitions).
  • If the TypeVar uses a 'default' argument (Python 3.13+), the fix omits the default, altering the inferred type when the parameter is omitted.
  • If the TypeVar has a 'bound' constraint, the fix does not preserve the bound in the new syntax, potentially changing type-checking behavior.
  • If the TypeVar is contravariant or covariant, the fix drops the variance keyword, and PEP 695 infers variance instead, which may differ and affect subtyping relationships.
  • If multiple functions share the same TypeVar, rewriting one function leaves the shared variable defined but may cause mismatches if other functions are not also rewritten.
  • If the TypeVar is used in a default argument value (e.g., def f(x: T = SomeDefault)), the fix does not update the default expression, leaving a reference to an undefined name after removal.
  • If the TypeVar is used in a type ignore comment or string annotation nearby, removing the variable definition may cause those references to become unresolved.
  • If the file contains a conditional import or definition of the TypeVar (e.g., inside an if block), the fix may hoist or misplace the removal, causing syntax errors.
  • If the TypeVar is aliased via import (e.g., from mod import TypeVar as TV), the rule may not detect it and leave the alias while incorrectly adding a type parameter, resulting in mixed old/new style.
  • If the function is decorated, the fix inserts type parameters before the decorator, which is invalid syntax.
  • If the function has overlapping type parameters with another generic function in the same scope, the fix may introduce duplicate or conflicting type parameter names.
  • If the code uses a stringized annotation (from __future__ import annotations) and the TypeVar is referenced in a string, removing the definition may break runtime evaluation of annotations.

Programs

idresulttitlehazard
r1-p001silent prediction offContext manager without close() - resource leak riskcontext managers that are not files, objects with write() but no close()
r1-p002silent prediction offDecorator placement breaks syntaxIf the function is decorated, the fix inserts type parameters before the decorator, which is invalid syntax.
r1-p003silent prediction offVariance dropped in PEP 695 rewriteIf the TypeVar is contravariant or covariant, the fix drops the variance keyword, and PEP 695 infers variance instead, which may differ and affect subtyping relationships.
r1-p004silent prediction offMutable default argument capturemutable default arguments and aliasing after a rewrite
r1-p005silent prediction offTruthiness and identity checkstruthiness of custom __bool__/__len__, None vs falsy, 'is' vs '=='
r1-p006silent prediction offUnresolved reference in type ignore or string annotationIf the TypeVar is used in a type ignore comment or string annotation nearby, removing the variable definition may cause those references to become unresolved.
r1-p007silent prediction offClass vs instance attribute interactionclass attributes vs instance attributes, descriptors, properties with side effects
r1-p008silent prediction offException handling and finally clausesexceptions raised inside the rewritten code, finally/else clauses, exception chaining
r2-p001silent prediction offTypeVar referenced in string annotation becomes unresolved after rewriteUnresolved reference in type ignore or string annotation
r2-p002silent prediction offRuntime evaluation of TypeVar annotation fails after removal due to typing-only import assumptiontype annotations evaluated at runtime, typing-only imports
r2-p003silent prediction offCovariant TypeVar loses variance in PEP 695 rewrite, affecting subtype checksVariance dropped in PEP 695 rewrite
r2-p004silent prediction offBinary write fails after rewrite due to str/bytes confusion in reused bufferbytes vs str, encoding and newline handling, text vs binary modes
r2-p005silent prediction offModule-level TypeVar reused in another function breaks after local scoping rewriteRewriting changes scope from module-level to function-local
r2-p006silent prediction offAsync function rewritten with misplaced type parameters breaks await orderingasync def/await ordering, async generators
r2-p007silent prediction offShared TypeVar across functions causes mismatch when only one is rewrittenMultiple functions share TypeVar; rewriting one leaves others mismatched
r2-p008silent prediction offFile truncation occurs on rewrite due to mode confusion in buffered write loopfile modes and truncation, partial writes, non-str data passed to write

Sources

r1-p001 · Context manager without close() - resource leak risk
1from typing import TypeVar
2T = TypeVar('T')
3class Buffer:
4 def __init__(self): self.data = []
5 def write(self, x): self.data.append(x)
6 def __enter__(self): return self
7 # Note: no __exit__ or close!
8def process(x: T) -> T:
9 with Buffer() as b:
10 b.write(x)
11 return x
12result = process("hello")
13print(f"Buffer data: {result}")
r1-p002 · Decorator placement breaks syntax
1from typing import TypeVar
2T = TypeVar('T')
3import functools
4@functools.lru_cache(maxsize=128)
5def cached_func(x: T) -> T:
6 return x
7print(cached_func(42))
42
r1-p003 · Variance dropped in PEP 695 rewrite
1from typing import TypeVar
2T_co = TypeVar('T_co', covariant=True)
3class Container(Generic[T_co]):
4 def __init__(self, item): self.item = item
5 @property
6 def value(self) -> T_co:
7 return self.item
8c: Container[object] = Container("str")
9print(f"Is str-subtype of object? {isinstance(c.value, str)}")
r1-p004 · Mutable default argument capture
1from typing import TypeVar
2T = TypeVar('T')
3def append_to_list(x: T, lst=[]):
4 lst.append(x)
5 return lst
6r1 = append_to_list(1)
7r2 = append_to_list(2)
8print(f"List 1: {r1}, List 2: {r2}, Same object: {r1 is r2}")
List 1: [1, 2], List 2: [1, 2], Same object: True
r1-p005 · Truthiness and identity checks
1from typing import TypeVar
2T = TypeVar('T')
3class FakeBool:
4 def __init__(self, val): self.val = val
5 def __bool__(self): return self.val is not None
6 def __eq__(self, other): return isinstance(other, FakeBool) and self.val == other.val
7def check(x: T) -> T:
8 if x is None:
9 return x
10 if x:
11 return FakeBool(True)
12 return x
13result = check(FakeBool(0))
14print(f"Result truthy: {bool(result)}, Result is FakeBool(True): {result == FakeBool(True)}")
Result truthy: True, Result is FakeBool(True): True
r1-p006 · Unresolved reference in type ignore or string annotation
1from typing import TypeVar
2T = TypeVar('T')
3def func(x: 'T') -> T: # type: ignore
4 return x
5print(func("test"))
test
r1-p007 · Class vs instance attribute interaction
1from typing import TypeVar
2T = TypeVar('T')
3class Tracking:
4 access_count = 0
5 def __init__(self, value): self._value = value
6 @property
7 def value(self) -> T:
8 Tracking.access_count += 1
9 return self._value
10obj = Tracking("hello")
11print(f"First access: {obj.value}, Count: {Tracking.access_count}")
12print(f"Second access: {obj.value}, Count: {Tracking.access_count}")
First access: hello, Count: 1
Second access: hello, Count: 2
r1-p008 · Exception handling and finally clauses
1from typing import TypeVar
2T = TypeVar('T')
3def risky(x: T) -> T:
4 try:
5 if x == 0:
6 raise ValueError("zero")
7 return x
8 except ValueError as e:
9 raise RuntimeError("bad") from e
10 finally:
11 print("cleanup")
12try:
13 risky(0)
14except RuntimeError as e:
15 print(f"Caught: {e}, Cause: {type(e.__cause__).__name__ if e.__cause__ else None}")
cleanup
Caught: bad, Cause: ValueError
r2-p001 · TypeVar referenced in string annotation becomes unresolved after rewrite
1from typing import TypeVar
2T = TypeVar('T')
3def f(x: T) -> 'list[T]': # String annotation uses T
4 return [x]
5print(f(1))
[1]
r2-p002 · Runtime evaluation of TypeVar annotation fails after removal due to typing-only import assumption
1from typing import TypeVar
2T = TypeVar('T')
3def f(x):
4 return x.__annotations__['x'] # Accesses annotation at runtime
5try:
6 result = f(1)
7except NameError as e:
8 print('NameError:', e)
r2-p003 · Covariant TypeVar loses variance in PEP 695 rewrite, affecting subtype checks
1from typing import TypeVar
2T_co = TypeVar('T_co', covariant=True)
3def f(x: T_co) -> T_co:
4 return x
5class A: pass
6class B(A): pass
7print(isinstance(f(B()), A)) # Should be True; may break if variance inferred incorrectly
True
r2-p004 · Binary write fails after rewrite due to str/bytes confusion in reused buffer
1from typing import TypeVar
2T = TypeVar('T')
3def process(data: T) -> T:
4 with open('tmp.bin', 'wb') as f:
5 f.write(data) # Expects bytes
6 return data
7try:
8 process(b'hello')
9except TypeError as e:
10 print('TypeError:', e)
11finally:
12 import os
13 if os.path.exists('tmp.bin'):
14 os.remove('tmp.bin')
r2-p005 · Module-level TypeVar reused in another function breaks after local scoping rewrite
1from typing import TypeVar
2T = TypeVar('T')
3def f(x: T) -> T:
4 return x
5def g(y: T) -> str: # Reuses T from module scope
6 return f(y)
7print(g(42))
42
r2-p006 · Async function rewritten with misplaced type parameters breaks await ordering
1from typing import TypeVar
2T = TypeVar('T')
3async def fetch(x: T) -> T:
4 await asyncio.sleep(0.01) # type: ignore
5 return x
6import asyncio
7async def main():
8 result = await fetch('hello')
9 print(result)
10asyncio.run(main())
hello
r2-p007 · Shared TypeVar across functions causes mismatch when only one is rewritten
1from typing import TypeVar
2T = TypeVar('T')
3def identity(x: T) -> T:
4 return x
5def wrapper(x: T) -> T: # Still uses module T
6 return identity(x)
7print(wrapper('test')) # May fail if identity is rewritten but wrapper not
test
r2-p008 · File truncation occurs on rewrite due to mode confusion in buffered write loop
1from typing import TypeVar
2T = TypeVar('T')
3def log_message(msg: T) -> None:
4 with open('log.txt', 'w') as f: # Truncates each call
5 f.write(str(msg))
6log_message('first')
7with open('log.txt', 'r') as f:
8 print(f.read())
first