Stop ignoring asserts when running in optimized mode

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 do assert a == b it can tell you what a and b were if it fails

3 Likes