I place many checks of the program state, whose failure would indicate a bug in the code. In such cases, I’d love to use assert condition simply because it reads nicer than if not condition: raise MyException.
Using assert instead of raise has two problems.
-
assertdoes not allow to specify the exception to be raised, so catching it later becomes hard (catchingAssertionErrormay catch too much). -
assertis disabled when -O flag is passed to the interpreter.
In my environment any bug in the code requires that I discard any results until the bug is identified and fixed. Therefore, there’s no point catching exceptions raised by the above checks. Thus, problem #1 is irrelevant in my situation.
Problem #2 is serious. I want my checks to remain in production code, since correctness is far more important than performance in my environment. Few people use -O flag today; but one day I or someone else may prefer to use it (e.g., to suppress code behind if __debug__, or because -O might actually optimize code in the future). Since all my assert statements must remain active in the production code, I’ll need to replace all assert statements with something else. Is there any way to force assert to stay despite the -O flag?
By the way, I’m planning to customize the behavior of assert by printing variable values from the line that caused the assert to fail. I think I can do it by replacing sys.excepthook with my own function that catches AssertionError, reads the traceback, finds the relevant source code, prints the variables from the relevant line, and then reraises the exception. If anyone sees a problem with that, please let me know.
Just don’t use assertions if they aren’t what you need. Instead be explicit that you’ll throw this exception if some condition is violated. The assert statement always carries a “I may or may not be run at all” side. It’s less hacky, less astonishing, less likely to break in the future, and does not require you to prevent users from adding
-O.If you just want to save typing, you can do so. Create a function like this (a more specific name is highly recommended) and use it instead of
assert: