fixhunt

ruff RUF106

labelled unknown
Runs / 2026-10-17T21-51-10-336Z-eb9n-ruff-RUF106ruff 0.17.12026-10-17 21:51 UTC8 programs × 2 round(s)12 programs, 10 fired, 10 fixed, 0 findings, 0 rejectedmodel cost $0.01

Analysis Nemotron 3 Super

Flags Ruff-specific suppression comments using numeric rule codes instead of human-readable rule names.

Fix: Replaces numeric rule codes in Ruff suppression comments with their corresponding human-readable rule names (e.g., F401 → unused-import), preserving comment structure, spacing, and non-numeric content.

12 hazards
  • Rewriting ignore[F401] to ignore[unused-import] assumes the mapping is correct; if Ruff’s internal rule name for F401 changes or differs in a plugin, the fix may apply an incorrect or nonexistent rule name.
  • If a comment contains a code like 999 that is not a valid Ruff rule, replacing it with a fabricated name (e.g., ignore[999] → ignore[unknown]) could produce an invalid suppression that Ruff ignores or misinterprets.
  • In a disable comment like ruff: disable[F401,F841], rewriting to named rules could fail if one code maps to a name that Ruff does not recognize as a suppressible rule (e.g., a reporting-only rule), potentially leaving violations unsuppressed.
  • The fix does not preserve inline comments after the suppression (e.g., # ruff: ignore[F401] # temporary) because it may discard trailing text when reconstructing the comment, dropping meaningful annotations.
  • If the suppression comment contains non-ASCII characters or unusual whitespace (e.g., # ruff: ignore[F401 ]), the fix might normalize or drop them during parsing/reconstruction, altering the comment’s appearance or encoding.
  • In a multiline string or docstring that resembles a suppression comment (e.g., """ # ruff: ignore[F401] """), the tool might incorrectly apply the fix inside the string, corrupting the literal content.
  • If the code uses a custom Ruff plugin that assigns F401 to a non-standard rule (e.g., a project-specific lint), replacing F401 with 'unused-import' would suppress the wrong rule or fail to suppress the intended one.
  • The fix may interfere with source control or review tools if it changes comments in a way that obscures the original intent (e.g., replacing a ticket number-associated code like F401#[fix:123] with a generic name).
  • In a file with mixed tabs and spaces in comments, the rewrite might alter indentation within the comment line, potentially violating whitespace policies even though comments are usually exempt.
  • If the suppression comment is part of a larger comment block processed by a documentation tool (e.g., Sphinx), changing rule codes to names could break parsing if the tool expects numeric codes for cross-referencing.
  • The fix does not account for conditional suppression via environment variables or pragmas embedded in the comment (e.g., # ruff: ignore[F401] if DEBUG), and rewriting could break such logic if the tool strips or reorders conditional syntax.
  • If the same numeric code appears multiple times in a comment (e.g., ignore[F401,F401]), the deduplication or reordering during fix application could alter the suppression semantics if order or repetition were significant (though Ruff treats them as a set).

Programs

idresulttitlehazard
r1-p001silent prediction offInvalid rule code replacement produces unknown suppressionIf a comment contains a code like 999 that is not a valid Ruff rule, replacing it with a fabricated name (e.g., ignore[999] → ignore[unknown]) could produce an invalid suppression that Ruff ignores or
r1-p002fix okEvaluation order and side effects in tuple assignment with ignored expressionEvaluation order and side effects when expressions are merged, duplicated or deleted
r1-p003fix okMixed whitespace in comment preserved but visual alignment misleadingIn a file with mixed tabs and spaces in comments, the rewrite might alter indentation within the comment line, potentially violating whitespace policies even though comments are usually exempt.
r1-p004fix okDict with function values affected by ignored variabledict ordering, duplicate keys, __hash__/__eq__ overrides, sets
r1-p005fix okStar-import side effect depends on ignored flagstar-imports, module-level side effects, __all__
r1-p006fix okDocstring attached to function whose body has ignored varcomments and docstrings attached to the removed or moved code
r1-p007fix okTrailing inline comment discarded during suppression rewriteThe fix does not preserve inline comments after the suppression (e.g., # ruff: ignore[F401] # temporary) because it may discard trailing text when reconstructing the comment, dropping meaningful anno
r1-p008fix okSphinx-like comment block broken by numeric-to-name change in suppressionsIf the suppression comment is part of a larger comment block processed by a documentation tool (e.g., Sphinx), changing rule codes to names could break parsing if the tool expects numeric codes for cr
r2-p001fix okDisable comment with potential invalid rule name after rewriteRewriting numeric codes to names could produce unrecognized rule names (e.g., reporting-only rules), leaving violations unsuppressed.
r2-p002fix okConditional suppression broken by rewriteFix does not preserve conditional syntax like 'if DEBUG' in suppression comments, breaking logic-dependent suppression.
r2-p003silent prediction offIncorrect rule name mapping due to plugin or version mismatchFix assumes static mapping; if plugin changes F401 meaning, rewrite applies wrong suppression.
r2-p004fix okNon-ASCII whitespace in suppression commentFix might normalize or drop non-ASCII or unusual whitespace (e.g., NBSP) during parsing/reconstruction, altering comment appearance or encoding.

Sources

r1-p001 · Invalid rule code replacement produces unknown suppression
1x = []
2# Simulate conditional execution based on whether suppression works
3for i in range(2):
4 if i == 0:
5 # Import that should trigger F401 if not suppressed
6 import sys # ruff: ignore[999]
7 x.append('imported')
8 else:
9 x.append('rechecked')
10print(len(x))
2
r1-p002 · Evaluation order and side effects in tuple assignment with ignored expression
1def f():
2 print('side', end='')
3 return 1
4# Side effect in ignored expression: function call with print
5a, b = f(), 2 # ruff: ignore[F841]
6print(a, b)
--- orig.py	2026-10-17 17:51:25.773306553 -0400
+++ fixed.py	2026-10-17 17:51:25.925327512 -0400
@@ -2,5 +2,5 @@
     print('side', end='')
     return 1
 # Side effect in ignored expression: function call with print
-a, b = f(), 2  # ruff: ignore[F841]
+a, b = f(), 2  # ruff: ignore[unused-variable]
 print(a, b)
side1 2
r1-p003 · Mixed whitespace in comment preserved but visual alignment misleading
1# Configuration with mixed whitespace # ruff: ignore[W291]
2value = 42
3# After rewrite, comment still has \t but linters may warn
4print(value)
--- orig.py	2026-10-17 17:51:26.020340608 -0400
+++ fixed.py	2026-10-17 17:51:26.159359747 -0400
@@ -1,4 +1,4 @@
-# Configuration	with mixed	whitespace  # ruff: ignore[W291]
+# Configuration	with mixed	whitespace  # ruff: ignore[trailing-whitespace]
 value = 42
 # After rewrite, comment still has \t but linters may warn
 print(value)
42
r1-p004 · Dict with function values affected by ignored variable
1def get_key():
2 return 'dynamic'
3# Ignored variable used in dict construction
4tmp = get_key() # ruff: ignore[F841]
5d = {tmp: 'value', 'static': 1}
6print(d.get('dynamic', 'missing'))
--- orig.py	2026-10-17 17:51:26.255372965 -0400
+++ fixed.py	2026-10-17 17:51:26.417395270 -0400
@@ -1,6 +1,6 @@
 def get_key():
     return 'dynamic'
 # Ignored variable used in dict construction
-tmp = get_key()  # ruff: ignore[F841]
+tmp = get_key()  # ruff: ignore[unused-variable]
 d = {tmp: 'value', 'static': 1}
 print(d.get('dynamic', 'missing'))
value
r1-p005 · Star-import side effect depends on ignored flag
1__all__ = ['CONDITION']
2CONDITION = False
3if CONDITION:
4 from os import * # ruff: ignore[F403]
5 # If not suppressed, F403 triggers; side effect is polluting namespace
6print('CONDITION' in globals())
--- orig.py	2026-10-17 17:51:26.516408902 -0400
+++ fixed.py	2026-10-17 17:51:26.681431620 -0400
@@ -1,6 +1,6 @@
 __all__ = ['CONDITION']
 CONDITION = False
 if CONDITION:
-    from os import *  # ruff: ignore[F403]
+    from os import *  # ruff: ignore[undefined-local-with-import-star]
     # If not suppressed, F403 triggers; side effect is polluting namespace
 print('CONDITION' in globals())
True
r1-p006 · Docstring attached to function whose body has ignored var
1def process():
2 """Process data if flag is set."""
3 flag = True # ruff: ignore[F841]
4 if flag:
5 return 'ok'
6 return 'fail'
7print(process())
--- orig.py	2026-10-17 17:51:26.780445251 -0400
+++ fixed.py	2026-10-17 17:51:26.936466731 -0400
@@ -1,6 +1,6 @@
 def process():
     """Process data if flag is set."""
-    flag = True  # ruff: ignore[F841]
+    flag = True  # ruff: ignore[unused-variable]
     if flag:
         return 'ok'
     return 'fail'
ok
r1-p007 · Trailing inline comment discarded during suppression rewrite
1threshold = 10 # ruff: ignore[F841] # temporarily ignore while debugging
2value = 5
3if value > threshold:
4 print('high')
5else:
6 print('low') # Expected: 'low'
--- orig.py	2026-10-17 17:51:27.036480492 -0400
+++ fixed.py	2026-10-17 17:51:27.197502627 -0400
@@ -1,4 +1,4 @@
-threshold = 10  # ruff: ignore[F841]  # temporarily ignore while debugging
+threshold = 10  # ruff: ignore[unused-variable]  # temporarily ignore while debugging
 value = 5
 if value > threshold:
     print('high')
low
r1-p008 · Sphinx-like comment block broken by numeric-to-name change in suppressions
1##
2# This section covers error handling (see RFC 999)
3# ruff: ignore[E501] # Line too long in doc example
4# See also: @ref error-handling
5value = 'error'
6print('loaded' if value else 'failed')
--- orig.py	2026-10-17 17:51:27.296516238 -0400
+++ fixed.py	2026-10-17 17:51:27.473540573 -0400
@@ -1,6 +1,6 @@
 ##
 # This section covers error handling (see RFC 999)
-# ruff: ignore[E501]  # Line too long in doc example
+# ruff: ignore[line-too-long]  # Line too long in doc example
 # See also: @ref error-handling
 value = 'error'
 print('loaded' if value else 'failed')
loaded
r2-p001 · Disable comment with potential invalid rule name after rewrite
1import sys
2# ruff: disable[F403]
3from star import *
4print('star imported')
5# This line should trigger F403 if suppression fails
6if False:
7 from star import wildcard # noqa: F403
--- orig.py	2026-10-17 17:52:22.068753513 -0400
+++ fixed.py	2026-10-17 17:52:22.456802745 -0400
@@ -1,5 +1,5 @@
 import sys
-# ruff: disable[F403]
+# ruff: disable[undefined-local-with-import-star]
 from star import *
 print('star imported')
 # This line should trigger F403 if suppression fails
r2-p002 · Conditional suppression broken by rewrite
1DEBUG = True
2# ruff: ignore[F401] if DEBUG
3import os # This should be ignored only if DEBUG is True
4if not DEBUG:
5 print(os.path) # This line should cause F401 if suppression failed
6else:
7 print('suppression active')
--- orig.py	2026-10-17 17:52:22.666829391 -0400
+++ fixed.py	2026-10-17 17:52:22.836850961 -0400
@@ -1,5 +1,5 @@
 DEBUG = True
-# ruff: ignore[F401] if DEBUG
+# ruff: ignore[unused-import] if DEBUG
 import os  # This should be ignored only if DEBUG is True
 if not DEBUG:
     print(os.path)  # This line should cause F401 if suppression failed
suppression active
r2-p003 · Incorrect rule name mapping due to plugin or version mismatch
1import ast
2import re
3with open(__file__, 'r') as f:
4 lines = f.readlines()
5target_line = None
6for i, line in enumerate(lines):
7 if '# ruff: ignore[F401]' in line:
8 target_line = i
9 break
10if target_line is None:
11 print('suppression comment not found')
12 exit(1)
13comment = lines[target_line]
14# Check if the comment has been rewritten to a name that is not the expected one for our intent
15# We intended to suppress a hypothetical rule 'custom-rule', but we used F401.
16# The fix will change it to 'unused-import'.
17# If the fix produces a string that is not 'unused-import', we consider it incorrect for our intent.
18# We look for the pattern ignore[...] and extract the content.
19match = re.search(r'ignore\[([^]]+)\]', comment)
20if not match:
21 print('no ignore found')
22 exit(1)
23content = match.group(1)
24# We expected the fix to produce 'unused-import' for F401
25# If it produces something else, it's wrong for our goal (even if it's a valid rule)
26if content == 'unused-import':
27 print('suppression rewritten correctly for intent')
28 print(42)
29else:
30 print(f'suppression rewritten to unexpected content: {content}')
31 print(0)
suppression rewritten to unexpected content: F401
0
r2-p004 · Non-ASCII whitespace in suppression comment
1msg = 'start'
2# ruff: ignore[F401 ] # Note: \u00A0 is NO-BREAK SPACE after F401
3if msg:
4 print(msg)
5# After fix, if NBSP is stripped, the comment becomes '# ruff: ignore[F401]'
6# We detect if the NBSP is preserved by checking the raw byte representation of the comment.
7# We print a trace that depends on whether the NBSP is still present.
--- orig.py	2026-10-17 17:52:23.083882287 -0400
+++ fixed.py	2026-10-17 17:52:23.240902179 -0400
@@ -1,7 +1,7 @@
 msg = 'start'
-# ruff: ignore[F401 ]  # Note: \u00A0 is NO-BREAK SPACE after F401
+# ruff: ignore[unused-import ]  # Note: \u00A0 is NO-BREAK SPACE after F401
 if msg:
     print(msg)
-# After fix, if NBSP is stripped, the comment becomes '# ruff: ignore[F401]' 
+# After fix, if NBSP is stripped, the comment becomes '# ruff: ignore[unused-import]' 
 # We detect if the NBSP is preserved by checking the raw byte representation of the comment.
 # We print a trace that depends on whether the NBSP is still present.
start