ruff PIE808
labelled unknown
Analysis Nemotron 3 Super
Flags range() calls where the start argument is explicitly 0, since it is redundant.
Fix: Removes the first argument when it is exactly 0, transforming range(0, y) into range(y).
1 hazards
- If 'y' contains a side effect like a function call (e.g., range(0, func())), removing the explicit 0 changes nothing but relies on correct parsing; however, if the expression were misparenthesized, it could alter grouping—though this is unlikely given grammar constraints.
Programs
| id | result | title | hazard |
|---|---|---|---|
| r1-p001 | fix ok | Walrus Operator Scope Leak | walrus, comprehensions scoping, late binding in closures and lambdas |
| r1-p002 | fix ok | Generator Exhaustion in Sum | generators vs lists, iterators consumed once, lazy vs eager evaluation |
| r1-p003 | fix ok | Property with Side Effect in Default Arg | class attributes vs instance attributes, descriptors, properties with side effects |
| r1-p004 | fix ok | Function Call in Stop Argument | If 'y' contains a side effect like a function call (e.g., range(0, func())), removing the explicit 0 changes nothing but relies on correct parsing; however, if the expression were misparenthesized, it |
| r1-p005 | fix ok | Mutable Default Argument Capture | mutable default arguments and aliasing after a rewrite |
| r1-p006 | silent prediction off | Shadowed Built-in Range | shadowed builtins and names redefined later in the module |
| r1-p007 | fix ok | Keyword-Only Function with Default | keyword-only, positional-only, *args/**kwargs forwarding, defaults evaluated once |
| r1-p008 | fix ok | Comment Attached to Rewritten Code | comments and docstrings attached to the removed or moved code |
| r2-p001 | silent prediction off | Shadowed Built-in Range | shadowed builtins and names redefined later in the module |
| r2-p002 | fix ok | Comments on Rewritten Code | comments and docstrings attached to the removed or moved code |
| r2-p003 | invalid | Pathlib vs os.path Behavior | pathlib vs os.path behavior on relative paths, symlinks, missing files, bytes paths |
| r2-p004 | fix ok | Walrus Operator Scope Leak | walrus, comprehensions scoping, late binding in closures and lambdas |
| r2-p005 | fix ok | Exceptions in Rewritten Code | exceptions raised inside the rewritten code, finally/else clauses, exception chaining |
| r2-p006 | fix ok | Dict Ordering and Hashing | dict ordering, duplicate keys, __hash__/__eq__ overrides, sets |
| r2-p007 | fix ok | Generator Exhaustion | generators vs lists, iterators consumed once, lazy vs eager evaluation |
| r2-p008 | fix ok | Truthy Custom Objects | truthiness of custom __bool__/__len__, None vs falsy, 'is' vs '==' |
Sources
r1-p001 · Walrus Operator Scope Leak
1def make_checker(t):
2 xs = []
3 while (n := t) > 0:
4 xs.append(lambda: [i for i in range(0, n)])
5 t -= 1
6 return xs[0]
7
8f = make_checker(2)
9print(f())
--- orig.py 2026-10-17 16:29:00.516569454 -0400 +++ fixed.py 2026-10-17 16:29:00.685569456 -0400 @@ -1,7 +1,7 @@ def make_checker(t): xs = [] while (n := t) > 0: - xs.append(lambda: [i for i in range(0, n)]) + xs.append(lambda: [i for i in range(n)]) t -= 1 return xs[0]
[]
r1-p002 · Generator Exhaustion in Sum
1r = range(0, 3)
2gen = (x*2 for x in r)
3print(sum(gen))
4print(sum(gen)) # exhausted
--- orig.py 2026-10-17 16:29:00.792569457 -0400 +++ fixed.py 2026-10-17 16:29:00.959569459 -0400 @@ -1,4 +1,4 @@ -r = range(0, 3) +r = range(3) gen = (x*2 for x in r) print(sum(gen)) print(sum(gen)) # exhausted
6 0
r1-p003 · Property with Side Effect in Default Arg
1class Counter:
2 count = 0
3 @property
4 def value(self):
5 self.count += 1
6 return self.count
7
8c = Counter()
9def f(r=range(0, c.value)):
10 return list(r)
11
12print(f())
13print(f())
--- orig.py 2026-10-17 16:29:01.060569461 -0400 +++ fixed.py 2026-10-17 16:29:01.224569464 -0400 @@ -6,7 +6,7 @@ return self.count c = Counter() -def f(r=range(0, c.value)): +def f(r=range(c.value)): return list(r) print(f())
[0] [0]
r1-p004 · Function Call in Stop Argument
1state = 0
2
3def inc():
4 global state
5 state += 1
6 return state
7
8r = range(0, inc())
9print(list(r))
10r = range(0, inc())
11print(list(r))
--- orig.py 2026-10-17 16:29:01.322569466 -0400 +++ fixed.py 2026-10-17 16:29:01.487569469 -0400 @@ -5,7 +5,7 @@ state += 1 return state -r = range(0, inc()) +r = range(inc()) print(list(r)) -r = range(0, inc()) +r = range(inc()) print(list(r))
[0] [0, 1]
r1-p005 · Mutable Default Argument Capture
1def f(x=None, r=range(0, 3)):
2 if x is None:
3 x = []
4 x.extend(r)
5 return x
6
7print(f())
8print(f())
--- orig.py 2026-10-17 16:29:01.588569471 -0400 +++ fixed.py 2026-10-17 16:29:01.755569474 -0400 @@ -1,4 +1,4 @@ -def f(x=None, r=range(0, 3)): +def f(x=None, r=range(3)): if x is None: x = [] x.extend(r)
[0, 1, 2] [0, 1, 2]
r1-p006 · Shadowed Built-in Range
1range = lambda *a: list(__builtins__.range(*a))
2x = range(0, 2)
3print(x)
4del range
5x = range(0, 2) # now built-in
6print(list(x))
[0, 1] [0, 1]
r1-p007 · Keyword-Only Function with Default
1def f(*, r=range(0, 2)):
2 return sum(r)
3
4print(f())
5print(f())
--- orig.py 2026-10-17 16:29:01.987569479 -0400 +++ fixed.py 2026-10-17 16:29:02.156569483 -0400 @@ -1,4 +1,4 @@ -def f(*, r=range(0, 2)): +def f(*, r=range(2)): return sum(r) print(f())
1 1
r1-p008 · Comment Attached to Rewritten Code
1def f():
2 # This loop runs twice
3 for i in range(0, 2): # index
4 print(i)
--- orig.py 2026-10-17 16:29:02.261569486 -0400 +++ fixed.py 2026-10-17 16:29:02.428569491 -0400 @@ -1,4 +1,4 @@ def f(): # This loop runs twice - for i in range(0, 2): # index + for i in range(2): # index print(i)
r2-p001 · Shadowed Built-in Range
1range = lambda s, e=None: (list(range(s if e is not None else 0, e if e is not None else s)), 'redefined')[1]
2for i in range(0, 3):
3 print(f'i={i}', end=' ')
4print()
5print('done')
r2-p002 · Comments on Rewritten Code
1# This loop uses range(0, n) with a comment
2for i in range(0, 2): # iterates twice
3 print(i)
4# End of loop
--- orig.py 2026-10-17 16:29:08.219569765 -0400 +++ fixed.py 2026-10-17 16:29:08.382569776 -0400 @@ -1,4 +1,4 @@ # This loop uses range(0, n) with a comment -for i in range(0, 2): # iterates twice +for i in range(2): # iterates twice print(i) # End of loop
0 1
r2-p003 · Pathlib vs os.path Behavior (generated program does not parse: Traceback (most recent call last):)
1import os
2try:
3 os.symlink('nonexistent', 'link')
4except FileExistsError:
5 pass
6for i in range(0, 1):
7 p = os.path.exists('link')
8 print(f'exists: {p}')
9 try:
10 with open('link') as f:
11 print(f.read())
12 except Exception as e:
13 print(f'error: {type(e).__name__}: {e}')
14finally:
15 try:
16 os.unlink('link')
17 except:
18 pass
r2-p004 · Walrus Operator Scope Leak
1n = 5
2f = lambda: [j for i in range(0, n) if (j := i) is not None]
3print('Before:', f())
4n = 10
5print('After:', f())
--- orig.py 2026-10-17 16:29:08.620569793 -0400 +++ fixed.py 2026-10-17 16:29:08.782569805 -0400 @@ -1,5 +1,5 @@ n = 5 -f = lambda: [j for i in range(0, n) if (j := i) is not None] +f = lambda: [j for i in range(n) if (j := i) is not None] print('Before:', f()) n = 10 print('After:', f())
Before: [0, 1, 2, 3, 4] After: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
r2-p005 · Exceptions in Rewritten Code
1def f():
2 try:
3 for i in range(0, 1):
4 raise ValueError('bad')
5 except ValueError as e:
6 print(f'caught: {e}')
7 else:
8 print('no ex')
9 finally:
10 print('finally')
11f()
--- orig.py 2026-10-17 16:29:08.882569812 -0400 +++ fixed.py 2026-10-17 16:29:09.046569824 -0400 @@ -1,6 +1,6 @@ def f(): try: - for i in range(0, 1): + for i in range(1): raise ValueError('bad') except ValueError as e: print(f'caught: {e}')
caught: bad finally
r2-p006 · Dict Ordering and Hashing
1class K:
2 def __init__(self, v): self.v = v
3 def __hash__(self): return hash(self.v)
4 def __eq__(self, other): return self.v == other.v
5 def __repr__(self): return f'K({self.v})'
6d = {}
7for i in range(0, 2):
8 d[K(i)] = i * 10
9print('dict:', d)
10print('keys:', list(d.keys()))
--- orig.py 2026-10-17 16:29:09.144569831 -0400 +++ fixed.py 2026-10-17 16:29:09.308569844 -0400 @@ -4,7 +4,7 @@ def __eq__(self, other): return self.v == other.v def __repr__(self): return f'K({self.v})' d = {} -for i in range(0, 2): +for i in range(2): d[K(i)] = i * 10 print('dict:', d) print('keys:', list(d.keys()))
dict: {K(0): 0, K(1): 10}
keys: [K(0), K(1)]r2-p007 · Generator Exhaustion
1def gen():
2 for i in range(0, 3):
3 yield i
4 print(f'yielded {i}')
5g = gen()
6print('first sum:', sum(g))
7print('second sum:', sum(g)) # should be 0
--- orig.py 2026-10-17 16:29:09.410569852 -0400 +++ fixed.py 2026-10-17 16:29:09.580569865 -0400 @@ -1,5 +1,5 @@ def gen(): - for i in range(0, 3): + for i in range(3): yield i print(f'yielded {i}') g = gen()
yielded 0 yielded 1 yielded 2 first sum: 3 second sum: 0
r2-p008 · Truthy Custom Objects
1class T:
2 def __bool__(self): return False
3 def __len__(self): return 0
4 def __repr__(self): return 'T()'
5t = T()
6print(f't bool: {bool(t)}')
7print(f't len: {len(t)}')
8print(f't is None: {t is None}')
9print(f't == None: {t == None}')
10for i in range(0, 1):
11 if t:
12 print('truthy')
13 else:
14 print('falsy')
--- orig.py 2026-10-17 16:29:09.677569873 -0400 +++ fixed.py 2026-10-17 16:29:09.842569886 -0400 @@ -7,7 +7,7 @@ print(f't len: {len(t)}') print(f't is None: {t is None}') print(f't == None: {t == None}') -for i in range(0, 1): +for i in range(1): if t: print('truthy') else:
t bool: False t len: 0 t is None: False t == None: False falsy