ruff RUF050
labelled unknown
Analysis Nemotron 3 Super
Flags standalone 'if' statements whose bodies contain only 'pass' or ellipsis ('...').
Fix: Removes the entire 'if' statement if its condition is side-effect-free; otherwise replaces it with the condition as an expression statement.
8 hazards
- Rewrite drops inline or trailing comments attached to the 'if' line or indented block, altering source documentation.
- If the condition is a name like 'if x:', the fix treats it as side-effect-free and removes it, but 'x.__bool__()' might have side effects if overridden, changing behavior.
- When the condition has side effects (e.g., a function call), replacing 'if func(): pass' with 'func()' evaluates the condition once instead of potentially short-circuiting in larger contexts, though here it's standalone so evaluation count remains one—still, if the call was relied upon for truthiness in a now-removed branch, logic may mislead readers.
- In nested scopes, removing an 'if' block could inadvertently expose variables meant to be conditionally scoped (though Python lacks block scope, this affects readability and potential accidental reuse).
- If the 'if' statement is the only thing in a module or block, removing it may create an unexpected blank line or affect formatting-dependent tools.
- The fix may interfere with source‑generation tools that rely on the presence of syntactic scaffolding (like code‑generation templates) even when the body is a no‑op.
- If the ellipsis '...' is used intentionally as a stub (e.g., in API skeletons), removing the 'if' could delete a meaningful placeholder despite being semantically empty.
- When the condition involves chained comparisons or complex expressions, extracting it as a standalone statement may hinder debugging (e.g., breakpoint placement on the 'if' line vs. the expression line).
Programs
| id | result | title | hazard |
|---|---|---|---|
| r1-p001 | fix ok | star-imports-module-side-effects-all | star-imports, module-level side effects, __all__ |
| r1-p002 | fix ok | file-modes-truncation-partial-write-nonstr-data | file modes and truncation, partial writes, non-str data passed to write |
| r1-p003 | fix ok | only-statement-in-blank-line-formatting-tools | If the 'if' statement is the only thing in a module or block, removing it may create an unexpected blank line or affect formatting-dependent tools. |
| r1-p004 | fix ok | ellipsis-as-intentional-stub-api-skeleton | If the ellipsis '...' is used intentionally as a stub (e.g., in API skeletons), removing the 'if' could delete a meaningful placeholder despite being semantically empty. |
| r1-p005 | fix ok | keyword-only-positional-only-args-kwargs-forwarding-defaults-evaluated-once | keyword-only, positional-only, *args/**kwargs forwarding, defaults evaluated once |
| r1-p006 | silent prediction off | async-def-await-ordering-async-generators | async def/await ordering, async generators |
| r1-p007 | fix ok | mutable-default-arguments-aliasing-after-rewrite | mutable default arguments and aliasing after a rewrite |
| r1-p008 | fix ok | truthiness-custom-bool-len-none-falsy-is-vs-equals | truthiness of custom __bool__/__len__, None vs falsy, 'is' vs '==' |
| r2-p001 | silent prediction off | Evaluation Order Side Effects - Merged/Duplicated Condition | Rule merges duplicate conditions without preserving evaluation order or intermediate side effects. |
| r2-p002 | silent prediction off | Source Generation Scaffolding Dependency | Removing empty if blocks breaks template-based code generation that relies on structural markers. |
| r2-p003 | silent prediction off | Name Condition Overridden __bool__ Side Effect | Treating 'if x:' as side-effect-free ignores x.__bool__() which may mutate state. |
| r2-p004 | silent prediction off | Comment Stripping Alters Documentation | Fix removes inline/trailing comments on if line or in block, losing developer intent. |
| r2-p005 | invalid | Iterator Consumption in Condition | Duplicating condition expression consumes iterator twice when it should be once. |
| r2-p006 | silent prediction off | Chained Comparison Hinders Debugging | Extracting chained comparison as expression stmt breaks breakpoint utility on original if line. |
| r2-p007 | silent prediction off | Numeric Coercion Edge Case with Division | Fix alters timing/evaluation of numeric expressions involving coercion or rounding. |
| r2-p008 | silent prediction off | F-string Repr/Src in Condition with Nested Quotes | Condition expression contains f-string with nested quotes; duplication risks quote instability. |
Sources
r1-p001 · star-imports-module-side-effects-all
1__all__ = ['x']
2x = 1
3from mod import *
4if False:
5 ...
6print(x)
--- orig.py 2026-10-17 17:46:44.048674043 -0400 +++ fixed.py 2026-10-17 17:46:44.457761697 -0400 @@ -1,6 +1,4 @@ __all__ = ['x'] x = 1 from mod import * -if False: - ... print(x)
r1-p002 · file-modes-truncation-partial-write-nonstr-data
1with open('tmp.txt', 'w') as f:
2 f.write(b'abc')
3if 0:
4 pass
5with open('tmp.txt', 'r') as f:
6 print(f.read())
--- orig.py 2026-10-17 17:46:44.671807560 -0400 +++ fixed.py 2026-10-17 17:46:45.054889622 -0400 @@ -1,6 +1,4 @@ with open('tmp.txt', 'w') as f: f.write(b'abc') -if 0: - pass with open('tmp.txt', 'r') as f: print(f.read())
r1-p003 · only-statement-in-blank-line-formatting-tools
1if 1:
2 pass
3print(__name__)
--- orig.py 2026-10-17 17:46:45.272936265 -0400 +++ fixed.py 2026-10-17 17:46:45.428969643 -0400 @@ -1,3 +1 @@ -if 1: - pass print(__name__)
__main__
r1-p004 · ellipsis-as-intentional-stub-api-skeleton
1def f():
2 if True:
3 ...
4 return 1
5print(f())
--- orig.py 2026-10-17 17:46:45.534992323 -0400 +++ fixed.py 2026-10-17 17:46:45.692025914 -0400 @@ -1,5 +1,3 @@ def f(): - if True: - ... return 1 print(f())
1
r1-p005 · keyword-only-positional-only-args-kwargs-forwarding-defaults-evaluated-once
1def g(a, /, b, *, c=print('default')):
2 return a + b + len(str(c))
3if 0:
4 pass
5print(g(1, 2, c=3))
--- orig.py 2026-10-17 17:46:45.797048380 -0400 +++ fixed.py 2026-10-17 17:46:45.957082614 -0400 @@ -1,5 +1,3 @@ def g(a, /, b, *, c=print('default')): return a + b + len(str(c)) -if 0: - pass print(g(1, 2, c=3))
default 4
r1-p006 · async-def-await-ordering-async-generators
1async def gen():
2 if False:
3 yield 1
4 return 2
5import asyncio
6print(asyncio.run(gen()))
r1-p007 · mutable-default-arguments-aliasing-after-rewrite
1def f(x=[]):
2 if 0:
3 pass
4 x.append(1)
5 return x
6print(f())
7print(f())
--- orig.py 2026-10-17 17:46:46.408178966 -0400 +++ fixed.py 2026-10-17 17:46:46.573214211 -0400 @@ -1,6 +1,4 @@ def f(x=[]): - if 0: - pass x.append(1) return x print(f())
[1] [1, 1]
r1-p008 · truthiness-custom-bool-len-none-falsy-is-vs-equals
1class C:
2 def __bool__(self):
3 return True
4c = C()
5if c:
6 pass
7print(bool(c))
--- orig.py 2026-10-17 17:46:46.670234931 -0400 +++ fixed.py 2026-10-17 17:46:46.835270176 -0400 @@ -2,6 +2,4 @@ def __bool__(self): return True c = C() -if c: - pass print(bool(c))
True
r2-p001 · Evaluation Order Side Effects - Merged/Duplicated Condition
1counter = [0]
2def inc():
3 counter[0] += 1
4 return counter[0]
5val = []
6if inc() > 0:
7 val.append(inc()) # Should append 2
8print('inc calls:', counter[0], 'value:', val)
inc calls: 2 value: [2]
r2-p002 · Source Generation Scaffolding Dependency
1# GENERATED_CODE_START
2if TEMPLATE_FLAG:
3 pass # Stub for injected logic
4# GENERATED_CODE_END
5TEMPLATE_FLAG = False
6print('Template flag present:', 'GENERATED_CODE_START' in open(__file__).read())
r2-p003 · Name Condition Overridden __bool__ Side Effect
1class BoolCounter:
2 def __init__(self):
3 self.count = 0
4 def __bool__(self):
5 self.count += 1
6 return self.count < 2 # True once, then False
7x = BoolCounter()
8result = []
9if x:
10 result.append('first')
11if x: # Second eval should be False -> no append
12 result.append('second')
13print('bool calls:', x.count, 'results:', result)
bool calls: 2 results: ['first']
r2-p004 · Comment Stripping Alters Documentation
1debug_mode = False # Set via deploy script
2if debug_mode:
3 pass # Enable verbose logging in dev
4print('Debug comment preserved:', 'verbose logging' in open(__file__).read())
Debug comment preserved: True
r2-p005 · Iterator Consumption in Condition (generated program does not parse: Traceback (most recent call last):)
1def gen():
2 yield 1
3 yield 2
4 g = gen()
5if any(g): # Consumes first item (1), leaves generator exhausted
6 print('Second any:', list(g)) # Should be [], but fix may re-evaluate condition
7print('Generator after:', list(gen())) # Fresh gen for comparison
r2-p006 · Chained Comparison Hinders Debugging
1a, b, c = 1, 2, 3
2if a < b < c:
3 pass # Set breakpoint here to inspect a,b,c
4print('Chain holds:', a < b and b < c) # Same logic, but now expr stmt - no breakpoint hook
Chain holds: True
r2-p007 · Numeric Coercion Edge Case with Division
1x = 5
2y = 2
3if x / y > 2: # 2.5 > 2 -> True
4 pass
5print('Division result:', x / y)
6print('Comparison outcome:', x / y > 2)
7# If rule duplicates condition, division re-evaluated (same result, but hazard is expression reuse)
Division result: 2.5 Comparison outcome: True
r2-p008 · F-string Repr/Src in Condition with Nested Quotes
1name = "Alice"
2if f"User '{name}'" == "User 'Alice'": # Contains single quotes inside double
3 pass
4print('F-string evaluated:', f"User '{name}'")
5print('Match:', f"User '{name}'" == "User 'Alice'")
F-string evaluated: User 'Alice' Match: True