fixhunt

ruff UP048

labelled unknown
Runs / 2026-10-17T21-27-24-218Z-z60i-ruff-UP048ruff 0.17.12026-10-17 21:27 UTC8 programs × 2 round(s)16 programs, 12 fired, 12 fixed, 0 findings, 2 rejectedmodel cost $0.0033

Analysis Nemotron 3 Super

Flags `while 1:` loops and suggests replacing them with `while True:` for clarity.

Fix: Replace the literal integer 1 in the while condition with the boolean literal True, preserving all whitespace and formatting otherwise.

11 hazards
  • The rewrite changes the constant from int to bool, which could affect code that relies on the condition's type via type() or isinstance() checks.
  • If the loop condition is used in an expression elsewhere (e.g., assigned to a variable), the type change may break downstream logic expecting an integer.
  • In rare metaprogramming contexts where the AST node's constant value is inspected, the rewrite alters the observed value from 1 to True.
  • If the code is processed by tools that distinguish between 1 and True for optimization or serialization, the transformation may alter output.
  • Comments attached to the condition token (e.g., trailing comments on the same line) may be misplaced or lost during reformatting depending on the linter's formatting logic.
  • If the while statement is part of a larger compound statement parsed ambiguously, the rewrite could interfere with error recovery or parsing in malformed code snippets.
  • In code that deliberately uses 1 as a truthy integer for bitwise operations in the condition (though syntactically invalid as a standalone condition), the rewrite would not apply since such usage isn't a valid while condition.
  • The fix assumes the condition is a simple literal; if the condition were a more complex expression mistakenly parsed as '1' due to broken syntax, the rewrite could be incorrectly applied.
  • Changing 1 to True may affect debugging or introspection tools that display constant values in stack traces or frame locals.
  • If the code is run under a Python interpreter that treats 1 and True differently in edge cases (e.g., certain PyPy optimizations or sandboxed environments), behavioral differences could emerge.
  • In code that overrides the built-in True name in an outer scope (though irrelevant for the condition's evaluation), the rewrite might be misinterpreted as referencing the outer scope, though this does not change runtime behavior since True is resolved at compile time.

Programs

idresulttitlehazard
r1-p001fix okContext manager interactioncontext managers that are not files, objects with write() but no close()
r1-p002fix okCoercion and Decimal arithmeticint/float/bool coercion, Decimal, division and rounding
r1-p003fix okAsync generator interactionasync def/await ordering, async generators
r1-p004invalidDict ordering and hashingdict ordering, duplicate keys, __hash__/__eq__ overrides, sets
r1-p005fix ok prediction offSerialization distinctionIf the code is processed by tools that distinguish between 1 and True for optimization or serialization, the transformation may alter output.
r1-p006fix okGenerator consumptiongenerators vs lists, iterators consumed once, lazy vs eager evaluation
r1-p007silent prediction offAST constant inspectionIn rare metaprogramming contexts where the AST node's constant value is inspected, the rewrite alters the observed value from 1 to True.
r1-p008fix okKeyword-only argument forwardingkeyword-only, positional-only, *args/**kwargs forwarded, defaults evaluated once
r2-p001fix okDict ordering with duplicate keys and custom hash/eqdict ordering, duplicate keys, __hash__/__eq__ overrides, sets
r2-p002fix okDebugging/introspection visibility of constants in frameChanging 1 to True may affect debugging or introspection tools that display constant values in stack traces or frame locals.
r2-p003fix okEvaluation order and side effects in merged expressionsevaluation order and side effects when expressions are merged, duplicated or deleted
r2-p004fix okFile modes, truncation, partial writes, non-str datafile modes and truncation, partial writes, non-str data passed to write
r2-p005invalidShadowed builtins and names redefined latershadowed builtins and names redefined later in the module
r2-p006silentBitwise truthy integer in condition (near-miss: invalid syntax, so expect no trigger)In code that deliberately uses 1 as a truthy integer for bitwise operations in the condition (though syntactically invalid as a standalone condition), the rewrite would not apply since such usage isn'
r2-p007fix okType annotations evaluated at runtime, typing-only importstype annotations evaluated at runtime, typing-only imports
r2-p008fix okStar-imports, module-level side effects, __all__star-imports, module-level side effects, __all__

Sources

r1-p001 · Context manager interaction
1class Dummy:
2 def __enter__(self):
3 return self
4 def __exit__(self, *exc):
5 pass
6 def write(self, s):
7 self.data += s
8 return len(s)
9
10out = []
11with Dummy() as d:
12 d.data = ''
13 i = 0
14 while 1:
15 if i >= 2:
16 break
17 d.write(str(i))
18 i += 1
19 out.append(d.data)
20print(''.join(out))
--- orig.py	2026-10-17 17:27:33.121300495 -0400
+++ fixed.py	2026-10-17 17:27:33.306296530 -0400
@@ -11,7 +11,7 @@
 with Dummy() as d:
     d.data = ''
     i = 0
-    while 1:
+    while True:
         if i >= 2:
             break
         d.write(str(i))
01
r1-p002 · Coercion and Decimal arithmetic
1from decimal import Decimal, getcontext
2getcontext().prec = 6
3vals = []
4i = 0
5while 1:
6 if i == 3:
7 break
8 f = float(i) / 2
9 d = Decimal(str(f))
10 vals.append((f, d))
11 i += 1
12print(vals)
--- orig.py	2026-10-17 17:27:33.405294407 -0400
+++ fixed.py	2026-10-17 17:27:33.586290527 -0400
@@ -2,7 +2,7 @@
 getcontext().prec = 6
 vals = []
 i = 0
-while 1:
+while True:
     if i == 3:
         break
     f = float(i) / 2
[(0.0, Decimal('0.0')), (0.5, Decimal('0.5')), (1.0, Decimal('1.0'))]
r1-p003 · Async generator interaction
1async def gen():
2 i = 0
3 while 1:
4 if i >= 2:
5 break
6 yield i
7 i += 1
8
9async def main():
10 res = []
11 async for x in gen():
12 res.append(x)
13 print(res)
14
15import asyncio
16asyncio.run(main())
--- orig.py	2026-10-17 17:27:33.693288234 -0400
+++ fixed.py	2026-10-17 17:27:34.019281246 -0400
@@ -1,6 +1,6 @@
 async def gen():
     i = 0
-    while 1:
+    while True:
         if i >= 2:
             break
         yield i
[0, 1]
r1-p004 · Dict ordering and hashing (generated program does not terminate within the time limit)
1class BadKey:
2 def __init__(self, v):
3 self.v = v
4 def __hash__(self):
5 return hash(int(self.v))
6 def __eq__(self, other):
7 return isinstance(other, BadKey) and self.v == other.v
8
9m = {}
10k = BadKey(1)
11while 1:
12 if k in m:
13 break
14 m[k] = 'found'
15 k.v += 1
16print(list(m.keys()))
r1-p005 · Serialization distinction
1# This program checks if any tool distinguishes 1 vs True.
2# Since no such tool is used in stdlib execution,
3# we expect no behavioral change.
4# We still include a while 1: to satisfy the rule trigger.
5print('start')
6i = 0
7while 1:
8 if i:
9 break
10 i += 1
11print('end')
--- orig.py	2026-10-17 17:27:39.279169043 -0400
+++ fixed.py	2026-10-17 17:27:39.438165666 -0400
@@ -4,7 +4,7 @@
 # We still include a while 1: to satisfy the rule trigger.
 print('start')
 i = 0
-while 1:
+while True:
     if i:
         break
     i += 1
start
end
r1-p006 · Generator consumption
1def make_gen():
2 i = 0
3 while 1:
4 if i >= 3:
5 break
6 yield i
7 i += 1
8
9g = make_gen()
10first = list(g)
11second = list(g) # exhausted
12print(len(first), len(second))
--- orig.py	2026-10-17 17:27:39.539163521 -0400
+++ fixed.py	2026-10-17 17:27:39.699160123 -0400
@@ -1,6 +1,6 @@
 def make_gen():
     i = 0
-    while 1:
+    while True:
         if i >= 3:
             break
         yield i
3 0
r1-p007 · AST constant inspection
1import ast
2code = 'while 1:\n break'
3tree = ast.parse(code, mode='exec')
4wh_node = tree.body[0]
5const = wh_node.test # the condition
6if isinstance(const, ast.Constant):
7 print(const.value)
8else:
9 print(type(const))
1
r1-p008 · Keyword-only argument forwarding
1def outer(**kwargs):
2 def inner(*, limit=1):
3 i = 0
4 total = 0
5 while 1:
6 if i >= limit:
7 break
8 total += i
9 i += 1
10 return total
11 return inner(**kwargs)
12
13print(outer(limit=3))
--- orig.py	2026-10-17 17:27:39.932155175 -0400
+++ fixed.py	2026-10-17 17:27:40.107151462 -0400
@@ -2,7 +2,7 @@
     def inner(*, limit=1):
         i = 0
         total = 0
-        while 1:
+        while True:
             if i >= limit:
                 break
             total += i
3
r2-p001 · Dict ordering with duplicate keys and custom hash/eq
1class K:
2 def __init__(self, v):
3 self.v = v
4 def __hash__(self):
5 return hash(self.v)
6 def __eq__(self, other):
7 return isinstance(other, K) and self.v == other.v
8
9m = {}
10while 1:
11 m[K(1)] = 'a'
12 m[K(1)] = 'b' # duplicate key
13 break
14
15# Print to show dict size and values (depends on loop having run)
16print(len(m))
17for k, v in m.items():
18 print(f'{k.v}:{v}')
--- orig.py	2026-10-17 17:27:45.503037451 -0400
+++ fixed.py	2026-10-17 17:27:45.666034021 -0400
@@ -7,7 +7,7 @@
         return isinstance(other, K) and self.v == other.v
 
 m = {}
-while 1:
+while True:
     m[K(1)] = 'a'
     m[K(1)] = 'b'  # duplicate key
     break
1
1:b
r2-p002 · Debugging/introspection visibility of constants in frame
1def f():
2 while 1:
3 x = 1
4 y = True
5 # Frame inspection: show locals
6 frame = __import__('sys')._getframe(0)
7 print('x:', frame.f_locals['x'], type(frame.f_locals['x']))
8 print('y:', frame.f_locals['y'], type(frame.f_locals['y']))
9 break
10f()
--- orig.py	2026-10-17 17:27:45.769031854 -0400
+++ fixed.py	2026-10-17 17:27:45.932028425 -0400
@@ -1,5 +1,5 @@
 def f():
-    while 1:
+    while True:
         x = 1
         y = True
         # Frame inspection: show locals
x: 1 <class 'int'>
y: True <class 'bool'>
r2-p003 · Evaluation order and side effects in merged expressions
1i = 0
2while 1:
3 if i >= 2:
4 break
5 print(i)
6 i += 1
7# After loop, i should be 2
8print('final i:', i)
--- orig.py	2026-10-17 17:27:46.030026364 -0400
+++ fixed.py	2026-10-17 17:27:46.190023002 -0400
@@ -1,5 +1,5 @@
 i = 0
-while 1:
+while True:
     if i >= 2:
         break
     print(i)
0
1
final i: 2
r2-p004 · File modes, truncation, partial writes, non-str data
1with open('test.txt', 'w') as f:
2 while 1:
3 f.write(b'hello') # bytes, not str
4 break
5with open('test.txt', 'rb') as f:
6 data = f.read()
7 print(data)
8import os
9os.remove('test.txt')
--- orig.py	2026-10-17 17:27:46.295020796 -0400
+++ fixed.py	2026-10-17 17:27:46.679012729 -0400
@@ -1,5 +1,5 @@
 with open('test.txt', 'w') as f:
-    while 1:
+    while True:
         f.write(b'hello')  # bytes, not str
         break
 with open('test.txt', 'rb') as f:
r2-p005 · Shadowed builtins and names redefined later (generated program does not parse: Traceback (most recent call last):)
1True = 1 # shadow built-in True
2while 1:
3 print(True, type(True)) # Should be 1, int
4 break
5# Restore? Not needed; show effect
6print('After loop, True =', True, type(True))
7del True # restore built-in if possible
8try:
9 print(True)
10except Exception as e:
11 print(type(e).__name__, e)
r2-p006 · Bitwise truthy integer in condition (near-miss: invalid syntax, so expect no trigger)
1# This is invalid syntax; cannot be compiled.
2# while 1 & 1:
3# pass
4# Instead, show a valid loop that does not trigger because condition is not literal 1
5x = 1
6while x & 1: # x is variable, not literal
7 print(x)
8 x = 0
9print('done')
1
done
r2-p007 · Type annotations evaluated at runtime, typing-only imports
1from typing import List
2# Use annotation at runtime via __annotations__
3def f() -> List[int]:
4 while 1:
5 return [1]
6
7# Trigger annotation evaluation
8print(f.__annotations__['return'])
9# Call f to ensure loop ran
10print(f())
--- orig.py	2026-10-17 17:27:47.155002734 -0400
+++ fixed.py	2026-10-17 17:27:47.354998539 -0400
@@ -1,7 +1,7 @@
 from typing import List
 # Use annotation at runtime via __annotations__
 def f() -> List[int]:
-    while 1:
+    while True:
         return [1]
 
 # Trigger annotation evaluation
typing.List[int]
[1]
r2-p008 · Star-imports, module-level side effects, __all__
1__all__ = ['mod_val']
2mod_val = 1
3
4# Simulate star-import by exec
5ns = {}
6exec("from test_mod import *", ns, ns)
7# But we can't create file; instead, define inline and import
8# Use a trick: define a module-like dict and exec
9code = '''
10__all__ = ['mod_val']
11mod_val = 1
12'''
13local_ns = {}
14exec(code, local_ns, local_ns)
15# Now simulate while loop using imported-like name
16while 1:
17 print(local_ns['mod_val'])
18 break
--- orig.py	2026-10-17 17:27:47.471996085 -0400
+++ fixed.py	2026-10-17 17:27:47.865987820 -0400
@@ -13,6 +13,6 @@
 local_ns = {}
 exec(code, local_ns, local_ns)
 # Now simulate while loop using imported-like name
-while 1:
+while True:
     print(local_ns['mod_val'])
     break