fixhunt

ruff UP034

labelled unknown
Runs / 2026-10-17T21-20-06-237Z-ukw3-ruff-UP034ruff 0.17.12026-10-17 21:20 UTC8 programs × 2 round(s)16 programs, 2 fired, 2 fixed, 0 findings, 0 rejectedmodel cost $0.0054

Analysis Nemotron 3 Super

Flags unnecessary parentheses around expressions where they do not affect precedence or grouping.

Fix: Removes the outer pair of parentheses when they enclose a single expression and are not required for operator precedence, tuple creation, or semantic clarity.

12 hazards
  • Rewriting `return (yield x)` to `return yield x` changes it from yielding a value and returning None to a syntax error due to invalid yield placement.
  • Removing parentheses in `(lambda: x)()` alters grouping, causing the lambda to be applied to `x` instead of being called first.
  • Stripping parentheses from `((x))` may break code relying on the inner parentheses for visual grouping or tooling expectations, though semantically identical.
  • In `(x,)`, removing outer parentheses yields `x,`, which is still a tuple, but if mistakenly applied to `(x)` it becomes `x`, changing a tuple to a scalar.
  • For `f((x, y))`, removing outer parentheses gives `f(x, y)`, which unpacks the tuple and passes two arguments instead of one tuple argument.
  • In `assert (condition), message`, removing parentheses around `condition` results in `assert condition, message`, which is valid, but if applied to `(assert condition), message` it would break — however, the rule does not target this shape.
  • Comments immediately after the opening parenthesis like `(# comment x)` would be lost if the autofix removes the parentheses without preserving internal formatting.
  • In a tuple assignment like `((a, b)) = ((c, d))`, removing outer parentheses gives `(a, b) = (c, d)`, which is equivalent, but if nested incorrectly could be misapplied.
  • In `raise (Exception("err"))`, removing parentheses yields `raise Exception("err")`, which is equivalent, but if the expression were more complex, precedence might matter — though the rule avoids such cases.
  • In `[(i) for i in range(10)]`, removing parentheses yields `[i for i in range(10)]`, which is equivalent, but if the parentheses were part of a larger expression like `[(i) + 1]`, removal would change meaning — however, the rule does not fire there due to presence of `+`.
  • In f-strings like `f"{(x)}"`, the rule does not apply as it targets expressions outside string contexts; applying it incorrectly would break the f-string syntax.
  • In `isinstance((x), int)`, removing outer parentheses gives `isinstance(x, int)`, which is equivalent, but if written as `isinstance((x,), int)`, removing outer parentheses yields `isinstance(x,, int)` which is invalid — however, the rule does not fire on `(x,)` as it's a tuple.

Programs

idresulttitlehazard
r1-p001silent prediction offLambda call grouping hazardRemoving parentheses in `(lambda: x)()` changes grouping from calling the lambda then applying result to x, to defining a lambda that takes x as argument.
r1-p002silentF-string brace hazardIncorrectly removing parentheses in f"{(x)}" would break f-string syntax, but rule correctly does not target expressions inside string literals.
r1-p003silent prediction offList comprehension parentheses hazardRule removes parens in [(i) for i in range(10)] safely; hazard shown by contrast with [(i) + 1] where rule does not fire due to + operator.
r1-p004silent prediction offException handling with finally/elseRewriting raise (ValueError('')) inside try block; finally/else clauses execute deterministically to show rewriting did not alter control flow.
r1-p005silent prediction offSingleton tuple vs scalar hazardRemoving parentheses from (x,) yields x, (still tuple), but from (x) yields x (scalar); rule avoids (x,) due to comma.
r1-p006silent prediction offTuple assignment nesting hazardRule removes outer parens in ((a, b)) = ((c, d)) safely; incorrect nesting could misapply but rule does not target inner structures.
r1-p007silent prediction offAssert message form hazardRule removes parens around condition in assert (cond), msg safely; does not fire on (assert cond), msg which would be invalid.
r1-p008silent prediction offRaise expression parentheses hazardRule removes parens in raise (Exception('err')) safely; complex expressions avoided by rule due to precedence concerns.
r2-p001silent prediction offRaise exception parentheses - safe removalPrecedence in complex raise expressions
r2-p002fix okSingleton tuple vs scalar confusion(x,) remains tuple after fix, (x) becomes scalar
r2-p003silentContext manager close behaviorNon-file context manager with write but no close
r2-p004silent prediction offComment inside parentheses lost on rewriteComments after ( are stripped when parens removed
r2-p005fix okFunction call with tuple argument unpacking hazardf((x,y)) -> f(x,y) changes arg count
r2-p006silentBinary vs text file mode encodingBytes vs str in file I/O with encoding/newline
r2-p007silentisinstance with tuple vs scalar hazard (near-miss)isinstance((x),int) safe; isinstance((x,),int) not triggered by rule
r2-p008silentCustom __bool__ and truthinessTruth value testing with custom __bool__

Sources

r1-p001 · Lambda call grouping hazard
1x = 2
2result = (lambda: x)()
3print('Result:', result)
Result: 2
r1-p002 · F-string brace hazard
1x = 42
2s = f"{(x)}"
3print('F-string:', s)
F-string: 42
r1-p003 · List comprehension parentheses hazard
1vals = [(i) for i in range(3)]
2print('List comp:', vals)
3# Near-miss: parentheses here are not removed due to +
4vals2 = [(i) + 1 for i in range(3)]
5print('With plus:', vals2)
List comp: [0, 1, 2]
With plus: [1, 2, 3]
r1-p004 · Exception handling with finally/else
1try:
2 raise (ValueError('error'))
3except ValueError as e:
4 print('Caught:', str(e))
5else:
6 print('No exception')
7finally:
8 print('Finally block')
Caught: error
Finally block
r1-p005 · Singleton tuple vs scalar hazard
1t = (5,)
2print('Tuple:', t, type(t))
3s = (5)
4print('Scalar:', s, type(s))
Tuple: (5,) <class 'tuple'>
Scalar: 5 <class 'int'>
r1-p006 · Tuple assignment nesting hazard
1(a, b) = (1, 2)
2((c, d)) = ((3, 4))
3print('Assigned:', a, b, c, d)
Assigned: 1 2 3 4
r1-p007 · Assert message form hazard
1x = 5
2assert (x > 0), 'x positive'
3print('Assert passed')
Assert passed
r1-p008 · Raise expression parentheses hazard
1try:
2 raise (Exception('test'))
3except Exception as e:
4 print('Raised caught:', type(e).__name__, str(e))
Raised caught: Exception test
r2-p001 · Raise exception parentheses - safe removal
1import sys
2try:
3 raise (ValueError('err'))
4except ValueError as e:
5 print('Caught:', e)
Caught: err
r2-p002 · Singleton tuple vs scalar confusion
1def show(val):
2 print(type(val).__name__, val)
3x = 5
4show((x))
5show((x,))
--- orig.py	2026-10-17 17:20:29.470414771 -0400
+++ fixed.py	2026-10-17 17:20:29.643407252 -0400
@@ -1,5 +1,5 @@
 def show(val):
     print(type(val).__name__, val)
 x = 5
-show((x))
+show(x)
 show((x,))
int 5
tuple (5,)
r2-p003 · Context manager close behavior
1class Writer:
2 def __enter__(self): return self
3 def __exit__(self, *exc): pass
4 def write(self, s): self.data = s
5with (Writer()) as w:
6 w.write('test')
7print(getattr(w, 'data', 'none'))
test
r2-p004 · Comment inside parentheses lost on rewrite
1x = (# note
242)
3print('x =', x)
x = 42
r2-p005 · Function call with tuple argument unpacking hazard
1def f(*args):
2 print('len', len(args), 'args', args)
3t = (1, 2)
4f((t))
--- orig.py	2026-10-17 17:20:30.012391216 -0400
+++ fixed.py	2026-10-17 17:20:30.174384187 -0400
@@ -1,4 +1,4 @@
 def f(*args):
     print('len', len(args), 'args', args)
 t = (1, 2)
-f((t))
+f(t)
len 1 args ((1, 2),)
r2-p006 · Binary vs text file mode encoding
1with open('test.bin', 'wb') as f:
2 f.write(b'hello\n')
3with open('test.bin', 'rb') as f:
4 data = f.read()
5print('bytes:', repr(data))
6with open('test.txt', 'w', encoding='utf-8') as f:
7 f.write('hello\n')
8with open('test.txt', 'r', encoding='utf-8') as f:
9 data = f.read()
10print('text:', repr(data))
11import os
12os.remove('test.bin')
13os.remove('test.txt')
bytes: b'hello\n'
text: 'hello\n'
r2-p007 · isinstance with tuple vs scalar hazard (near-miss)
1x = 5
2print(isinstance((x), int))
3print(isinstance((x,), int))
True
False
r2-p008 · Custom __bool__ and truthiness
1class Num:
2 def __init__(self, n): self.n = n
3 def __bool__(self): return self.n != 0
4x = Num(0)
5if (x):
6 print('true')
7else:
8 print('false')
false