ruff PLR2044
labelled unknown
Analysis Nemotron 3 Super
Flags lines ending with a '#' character without following non-whitespace text.
Fix: Removes the trailing '#' and any whitespace immediately preceding it on the same line, leaving the rest of the line unchanged.
10 hazards
- If the '#' is part of a string literal (e.g., `s = "abc#" #`), removing it alters the string value.
- If the '#' is inside a byte string or f-string (e.g., `b"data#" #` or `f"{x}#" #`), the fix corrupts the literal content.
- If the line contains a backslash continuation before the '#' (e.g., `x = 1 \ #`), removing the '#' may break the continuation if whitespace handling changes.
- If the '#' appears in a decorator (e.g., `@decorator# #`), the fix could produce invalid syntax by merging tokens.
- If the '#' is in a type annotation comment (e.g., `x = 1 # type: int #`), the fix removes only the last '#', potentially leaving a malformed type comment.
- If the '#' is followed by a newline in a multi-line statement via implicit line joining (e.g., within parentheses), the fix may affect where the line breaks are interpreted.
- If the '#' is the only content on a line used to disable a linter directive via `# noqa` but written as `# #`, the fix removes both, disabling the intent.
- If the '#' is part of an emoji or non-ASCII symbol in a comment-like context (e.g., `x = 1 #馃榾 #`), the fix may leave invalid or confusing remnants.
- If the line is otherwise blank except for indentation and `#` (e.g., ` #`), the fix removes the '#' and may leave only whitespace, which could be insignificant but alters formatting.
- If the '#' is in a line that also contains a semicolon statement separator (e.g., `x=1; y=2 #`), the fix does not affect semantics but may mislead if the '#' was intended to start a comment.
Programs
| id | result | title | hazard |
|---|---|---|---|
| r1-p001 | fix ok | File Modes and Truncation - Partial Write Hazard | Rule removes trailing '#' from comment affecting file mode logic; after fix, incorrect file mode opens file in 'w' instead of 'a', causing truncation. |
| r1-p002 | fix ok | Dict Ordering and Duplicate Keys - Hash Collision After Rewrite | Rule removes trailing '#' from comment on dict key assignment; key expression changes from variable to literal due to whitespace removal, altering hash and causing duplicate key collision in dict cons |
| r1-p003 | fix ok | Byte String and F-string Literal Corruption | Rule removes trailing '#' from comment on line with f-string containing '#'; fix deletes the '#' from the f-string literal itself, changing runtime value. |
| r1-p004 | fix ok | Type Annotations Evaluated at Runtime | Rule removes trailing '#' from comment on line with forward reference in type annotation; fix breaks annotation resolution causing NameError at runtime when annotation is evaluated. |
| r1-p005 | silent prediction off | Emoji and Non-ASCII in Comment Context | Rule removes trailing '#' and preceding whitespace from line with emoji in comment; after fix, emoji becomes adjacent to code or corrupted due to incorrect whitespace removal, changing interpretation. |
| r1-p006 | invalid | Star-Imports and Module-Level Side Effects | Rule removes trailing '#' from comment on line with star-import; fix alters import statement by removing critical whitespace, causing __all__ to be misinterpreted or import to fail. |
| r1-p007 | fix ok | Truthiness of Custom __bool__ and None vs Falsy | Rule removes trailing '#' from comment on line assigning object with custom __bool__; fix alters line to remove whitespace causing unintended tuple creation, changing truthiness evaluation. |
| r1-p008 | fix ok | Mutable Default Arguments and Aliasing After Rewrite | Rule removes trailing '#' from comment on function definition with mutable default argument; fix alters indentation or line structure causing default argument to be re-evaluated or shared incorrectly |
| r2-p001 | silent prediction off | Type Annotation Comment | If the '#' is in a type annotation comment (e.g., `x = 1 # type: int #`), the fix removes only the last '#', potentially leaving a malformed type comment. |
| r2-p002 | fix ok | Backslash Continuation | If the line contains a backslash continuation before the '#' (e.g., `x = 1 \ #`), removing the '#' may break the continuation if whitespace handling changes. |
| r2-p003 | fix ok | Byte String and F-string Literal Corruption | If the '#' is inside a byte string or f-string (e.g., `b"data#" #` or `f"{x}#" #`), the fix corrupts the literal content. |
| r2-p004 | fix ok | String Formatting Edge Cases | string formatting edge cases: %, format, f-strings, repr vs str, nested quotes |
| r2-p005 | fix ok | Class Attributes vs Instance Attributes | class attributes vs instance attributes, descriptors, properties with side effects |
| r2-p006 | fix ok | Context Managers Not Files | context managers that are not files, objects with write() but no close() |
| r2-p007 | fix ok | Dict Ordering and Duplicate Keys | dict ordering, duplicate keys, __hash__/__eq__ overrides, sets |
| r2-p008 | fix ok | Bytes vs Str Encoding Newline | bytes vs str, encoding and newline handling, text vs binary modes |
Sources
r1-p001 路 File Modes and Truncation - Partial Write Hazard
1def log(msg):
2 mode = 'a' #
3 try:
4 with open('test.txt', mode) as f:
5 f.write(msg + '\\n')
6 f.write('partial') # Intentional partial write before close
7 except Exception as e:
8 print(type(e).__name__, str(e))
9 finally:
10 try:
11 with open('test.txt', 'r') as f:
12 print(f.read())
13 except:
14 print('File not readable')
15log('first')
16import os
17os.remove('test.txt')
--- orig.py 2026-10-17 17:06:12.006815277 -0400 +++ fixed.py 2026-10-17 17:06:12.175817133 -0400 @@ -1,5 +1,5 @@ def log(msg): - mode = 'a' # + mode = 'a' try: with open('test.txt', mode) as f: f.write(msg + '\\n')
first\npartial
r1-p002 路 Dict Ordering and Duplicate Keys - Hash Collision After Rewrite
1key = 'a'
2d = {key: 1, 'b': 2} #
3print(len(d))
4if 'a' in d:
5 print(d['a'])
6else:
7 print('missing')
8del d
9key = 'a'
10d = {key: 1, 'b': 2} # real comment
11print(len(d))
--- orig.py 2026-10-17 17:06:12.281818297 -0400 +++ fixed.py 2026-10-17 17:06:12.441820054 -0400 @@ -1,5 +1,5 @@ key = 'a' -d = {key: 1, 'b': 2} # +d = {key: 1, 'b': 2} print(len(d)) if 'a' in d: print(d['a'])
2 1 2
r1-p003 路 Byte String and F-string Literal Corruption
1x = 42
2s = f"Value: {x}#" #
3print(s)
4s2 = b"data#" #
5print(s2)
6# Recovery: reset and show correct behavior
7x = 42
8s = f"Value: {x}#" # real comment
9print(s)
10s2 = b"data#" # real comment
11print(s2)
--- orig.py 2026-10-17 17:06:12.538821119 -0400 +++ fixed.py 2026-10-17 17:06:12.710823007 -0400 @@ -1,7 +1,7 @@ x = 42 -s = f"Value: {x}#" # +s = f"Value: {x}#" print(s) -s2 = b"data#" # +s2 = b"data#" print(s2) # Recovery: reset and show correct behavior x = 42
Value: 42# b'data#' Value: 42# b'data#'
r1-p004 路 Type Annotations Evaluated at Runtime
1from typing import List, Optional
2Node = Optional['Node'] #
3def walk(n: Node) -> List[int]:
4 return [] if n is None else [n.val] + walk(n.left) + walk(n.right)
5class Node:
6 def __init__(self, val, left=None, right=None):
7 self.val = val
8 self.left = left
9 self.right = right
10try:
11 root = Node(1, Node(2), Node(3))
12 print(walk(root))
13except Exception as e:
14 print(type(e).__name__, str(e))
--- orig.py 2026-10-17 17:06:12.803824028 -0400 +++ fixed.py 2026-10-17 17:06:12.997826159 -0400 @@ -1,5 +1,5 @@ from typing import List, Optional -Node = Optional['Node'] # +Node = Optional['Node'] def walk(n: Node) -> List[int]: return [] if n is None else [n.val] + walk(n.left) + walk(n.right) class Node:
[1, 2, 3]
r1-p005 路 Emoji and Non-ASCII in Comment Context
1x = 1 #馃榾 #
2print(x)
3y = 2 #馃榾 #real
4print(y)
5# Show intended behavior after fix
6x = 1 #馃榾
7print(x)
1 2 1
r1-p006 路 Star-Imports and Module-Level Side Effects (generated program does not parse: Traceback (most recent call last):)
1from testmod import * #
2print(__all__ if '__all__' in globals() else 'no __all__')
3# Cleanup
4try:
5 del testmod
6 del __all__
7except:
8 pass
9# Recreate module state
10import sys
11if 'testmod' in sys.modules:
12 del sys.modules['testmod']
13exec("
14class testmod:
15 __all__ = ['A']
16 A = 5
17sys.modules['testmod'] = testmod
18", globals(), locals())
19from testmod import * # real comment
20print(__all__ if '__all__' in globals() else 'no __all__')
21print(A)
r1-p007 路 Truthiness of Custom __bool__ and None vs Falsy
1class T:
2 def __bool__(self): return False
3obj = T() #
4if obj:
5 print('true')
6else:
7 print('false')
8# Show correct behavior
9obj = T() # real comment
10if obj:
11 print('true')
12else:
13 print('false')
--- orig.py 2026-10-17 17:06:13.379830352 -0400 +++ fixed.py 2026-10-17 17:06:13.536832075 -0400 @@ -1,6 +1,6 @@ class T: def __bool__(self): return False -obj = T() # +obj = T() if obj: print('true') else:
false false
r1-p008 路 Mutable Default Arguments and Aliasing After Rewrite
1def f(x, lst=[]): #
2 lst.append(x)
3 return lst
4print(f(1))
5print(f(2))
6# Reset and show correct
7f.__defaults__ = ([],)
8print(f(1))
9print(f(2))
--- orig.py 2026-10-17 17:06:13.640833217 -0400 +++ fixed.py 2026-10-17 17:06:13.808835061 -0400 @@ -1,4 +1,4 @@ -def f(x, lst=[]): # +def f(x, lst=[]): lst.append(x) return lst print(f(1))
[1] [1, 2] [1] [1, 2]
r2-p001 路 Type Annotation Comment
1import typing
2x = [] # type: list[int] #
3if hasattr(typing, 'List'):
4 y = typing.List[int] # type: ignore #
5x.append(1)
6try:
7 z = x[0]
8 print('value:', z)
9except Exception as e:
10 print(type(e).__name__, str(e))
value: 1
r2-p002 路 Backslash Continuation
1x = 1 \
2 #
3y = 2
4print('sum:', x + y)
--- orig.py 2026-10-17 17:06:18.543887000 -0400 +++ fixed.py 2026-10-17 17:06:18.712888853 -0400 @@ -1,4 +1,4 @@ x = 1 \ - # + y = 2 print('sum:', x + y)
sum: 3
r2-p003 路 Byte String and F-string Literal Corruption
1data = b'hello#world' #
2f'{data}' #
3print(data)
--- orig.py 2026-10-17 17:06:18.808889905 -0400 +++ fixed.py 2026-10-17 17:06:18.984891835 -0400 @@ -1,3 +1,3 @@ -data = b'hello#world' # -f'{data}' # +data = b'hello#world' +f'{data}' print(data)
b'hello#world'
r2-p004 路 String Formatting Edge Cases
1name = 'Alice'
2greeting = 'Hello %s #' % name #
3formatted = 'Hi {0}!'.format(name) #
4fstring = f'Hey {name} #' #
5print(greeting, formatted, fstring, sep='|')
--- orig.py 2026-10-17 17:06:19.089892985 -0400 +++ fixed.py 2026-10-17 17:06:19.254894793 -0400 @@ -1,5 +1,5 @@ name = 'Alice' -greeting = 'Hello %s #' % name # -formatted = 'Hi {0}!'.format(name) # -fstring = f'Hey {name} #' # +greeting = 'Hello %s #' % name +formatted = 'Hi {0}!'.format(name) +fstring = f'Hey {name} #' print(greeting, formatted, fstring, sep='|')
Hello Alice #|Hi Alice!|Hey Alice #
r2-p005 路 Class Attributes vs Instance Attributes
1class A:
2 attr = 1 #
3 @property
4 def prop(self):
5 return self.attr #
6a = A()
7print(a.prop)
8a.attr = 2
9print(a.prop)
--- orig.py 2026-10-17 17:06:19.351895856 -0400 +++ fixed.py 2026-10-17 17:06:19.513897632 -0400 @@ -1,8 +1,8 @@ class A: - attr = 1 # + attr = 1 @property def prop(self): - return self.attr # + return self.attr a = A() print(a.prop) a.attr = 2
1 2
r2-p006 路 Context Managers Not Files
1class Writer:
2 def __enter__(self):
3 return self
4 def __exit__(self, *args):
5 pass
6 def write(self, s):
7 print(s, end='')
8with Writer() as w:
9 w.write('test') #
10print('done')
--- orig.py 2026-10-17 17:06:19.616898761 -0400 +++ fixed.py 2026-10-17 17:06:19.774900492 -0400 @@ -6,5 +6,5 @@ def write(self, s): print(s, end='') with Writer() as w: - w.write('test') # + w.write('test') print('done')
testdone
r2-p007 路 Dict Ordering and Duplicate Keys
1class Key:
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 self.v == other.v
8d = {}
9k1 = Key(1)
10k2 = Key(1)
11d[k1] = 'first' #
12d[k2] = 'second' #
13print(len(d), d[k1])
--- orig.py 2026-10-17 17:06:19.872901566 -0400 +++ fixed.py 2026-10-17 17:06:20.036903363 -0400 @@ -8,6 +8,6 @@ d = {} k1 = Key(1) k2 = Key(1) -d[k1] = 'first' # -d[k2] = 'second' # +d[k1] = 'first' +d[k2] = 'second' print(len(d), d[k1])
1 second
r2-p008 路 Bytes vs Str Encoding Newline
1text = 'hello\nworld' #
2encoded = text.encode('utf-8') #
3print(repr(text))
4print(repr(encoded))
5with open('tmp.bin', 'wb') as f:
6 f.write(encoded)
7with open('tmp.bin', 'rb') as f:
8 print(f.read())
--- orig.py 2026-10-17 17:06:20.134904437 -0400 +++ fixed.py 2026-10-17 17:06:20.302906278 -0400 @@ -1,5 +1,5 @@ -text = 'hello\nworld' # -encoded = text.encode('utf-8') # +text = 'hello\nworld' +encoded = text.encode('utf-8') print(repr(text)) print(repr(encoded)) with open('tmp.bin', 'wb') as f:
'hello\nworld' b'hello\nworld' b'hello\nworld'