ruff B011
labelled unknown
Analysis Nemotron 3 Super
The rule flags any use of 'assert False' because assertions are removed in optimized mode, making them unreliable for raising errors.
Fix: Replace 'assert False' with 'raise AssertionError', preserving any message argument as the error's argument if present.
10 hazards
- In optimized mode (-O), the original 'assert False' would be ignored and do nothing, while the fix raises an exception, changing program behavior from silent continuation to explicit error.
- If 'assert False' appears inside a lambda or list comprehension, replacing it with 'raise AssertionError' may break the expression context, as raise is a statement and cannot be used where an expression is expected (e.g., in a list comprehension filter or lambda body), causing a SyntaxError.
- When 'assert False' is used in a try block, the fix changes which exceptions are caught: the original would be skipped in -O mode, but the fix always raises, potentially altering exception handling flow even in normal mode if other exceptions are expected.
- If 'assert False' is followed by a comment on the same line, the autofix may drop or misplace the comment during rewriting, especially if the tool does not preserve trailing comments.
- In a class or module scope, 'assert False' is executed during definition; replacing it with 'raise AssertionError' changes the timing and visibility of the error—now raised at import time unconditionally, whereas in -O mode the original would be removed and no error raised.
- If 'assert False' is part of a larger expression via short-circuiting (e.g., 'assert False or x'), removing the assert changes evaluation: the original would short-circuit to False in normal mode (but be removed in -O), while the fix always raises, breaking any reliance on the assert returning None or enabling short-circuit.
- When 'assert False' has a message (e.g., 'assert False, msg'), the fix correctly passes msg to AssertionError, but if msg has side effects (e.g., a function call), those are now evaluated unconditionally, whereas in -O mode the original assert would be removed and the side effects would not occur.
- If the code relies on the fact that 'assert False' raises AssertionError only in non-optimized mode to conditionally disable checks, replacing it with a permanent raise breaks that intentional optimization-aware behavior.
- In nested functions, if 'assert False' is used and the fix is applied, the raised exception may interfere with introspection or debugging tools that expect AssertionError to originate from assert statements specifically.
- If 'assert False' appears in a string or comment (as text), the linter should not flag it, but if the autofix incorrectly modifies such occurrences (due to faulty pattern matching), it would corrupt documentation or example code.
Programs
| id | result | title | hazard |
|---|---|---|---|
| r2-p001 | fired, no fix | Trailing comment preservation | If 'assert False' is followed by a comment on the same line, the autofix may drop or misplace the comment. |
| r2-p002 | fired, no fix | Exception chaining in finally block | Exceptions raised inside the rewritten code may interfere with finally/else clauses or exception chaining expectations. |
| r2-p003 | invalid | Lambda expression context | If 'assert False' appears inside a lambda, replacing it with 'raise AssertionError' breaks expression context, causing SyntaxError. |
| r2-p004 | fired, no fix | Non-file context manager interaction | Context managers that are not files but have write() without close() may be misused if assert is replaced in __exit__ logic. |
| r2-p005 | invalid | Short-circuiting in expression | If 'assert False' is part of a larger expression via short-circuiting, removing it changes evaluation (returns None vs always raising). |
| r2-p006 | fired, no fix | Optimization-dependent behavior | If code relies on 'assert False' being removed in -O to disable checks, replacing with permanent raise breaks that intent. |
| r2-p007 | silent | False positive in string literal | If 'assert False' appears in a string or comment, the linter should not flag it, but faulty pattern matching may corrupt it. |
| r2-p008 | silent prediction off | Type annotation evaluated at runtime | If 'assert False' appears in a type annotation evaluated at runtime (e.g., via string annotation), replacing it breaks evaluation. |
Sources
r2-p001 · Trailing comment preservation
1flag = True
2if flag:
3 assert False # This comment must stay after fix
4print('after')
r2-p002 · Exception chaining in finally block
1try:
2 assert False
3except ValueError as e:
4 raise RuntimeError('caught') from e
5except AssertionError as e:
6 print('AssertionError caught:', e)
7finally:
8 print('finally ran')
AssertionError caught: finally ran
r2-p003 · Lambda expression context (generated program does not parse: Traceback (most recent call last):)
1f = lambda: assert False or 1
2try:
3 result = f()
4 print('result:', result)
5except SyntaxError as e:
6 print('SyntaxError:', e.msg)
r2-p004 · Non-file context manager interaction
1class SilentWriter:
2 def __enter__(self): return self
3 def __exit__(self, exc_type, exc_val, exc_tb):
4 if exc_type is AssertionError:
5 print('Silenced AssertionError')
6 return True
7 return False
8with SilentWriter():
9 assert False
10print('after context')
Silenced AssertionError after context
r2-p005 · Short-circuiting in expression (generated program does not parse: Traceback (most recent call last):)
1def get_flag():
2 print('get_flag called')
3 return False
4result = assert False or get_flag()
5print('result:', result)
r2-p006 · Optimization-dependent behavior
1__debug__ = True # simulate non-optimized
2if __debug__:
3 assert False # should raise only when debugging
4print('after assert')
r2-p007 · False positive in string literal
1code_str = 'assert False # inline comment'
2print('string contains:', code_str)
3# assert False # real assert -- commented out to avoid trigger
4print('no modification to string or comment')
string contains: assert False # inline comment no modification to string or comment
r2-p008 · Type annotation evaluated at runtime
1from __future__ import annotations
2def f() -> 'assert False':
3 return 42
4try:
5 ann = f.__annotations__['return']
6 print('annotation value:', ann)
7except Exception as e:
8 print('Annotation error:', type(e).__name__, str(e))
annotation value: 'assert False'