if __debug__
blocks are rarely used. I have seen it in very few libraries, mostly older code. Over time developers realised that libraries were abusing assert
for control flows, which made python -O
unreliable.
Part of the problem with assert
is the fact that a failed assert does not abort the process. It’s too easy and too common to catch and ignore the result of a failed assert
. Python’s assert
should really work more like C assert
. In C a failed assert(3) results in an abnormal termination of the program. In Python assert False
raises an AssertionError
, which is a subclass of Exception
. We should have changed the base class to BaseException
or treat a failed assert as unrecoverable error (e.g. abort with Py_FatalError
).
Nathaniel explained to me that pytest’s use of assert
is not affected by the optimized flag. He wrote:
pytest transforms the source AST for test files before compilation, to replace
assert
s with annotated always-present assertions. that’s also how if you doassert a == b
it can tell you whata
andb
were if it fails