Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python assert -- improved introspection of failure?

This is a rather useless assertion error; it does not tell the values of the expression involved (assume constants used are actually variable names):

$ python -c "assert 6-(3*2)"
[...]
AssertionError

Is there a better assert implementation in Python that is more fancy? It must not introduce additional overhead over execution (except when assert fails) .. and must turn off if -O flag is used.

Edit: I know about assert's second argument as a string. I don't want to write one .. as that is encoded in the expression that is being asserted. DRY (Don't Repeat Yourself).

like image 289
Sridhar Ratnakumar Avatar asked Aug 20 '09 20:08

Sridhar Ratnakumar


People also ask

What happens when Python assert fails?

If an assertion fails, then your program should crash because a condition that was supposed to be true became false. You shouldn't change this intended behavior by catching the exception with a try … except block. A proper use of assertions is to inform developers about unrecoverable errors in a program.

What happens if an assert statement fails?

If an assertion fails, the assert() macro arranges to print a diagnostic message describing the condition that should have been true but was not, and then it kills the program.

Should you use asserts in Python?

Python's assert statement is a debugging aid, not a mechanism for handling run-time errors. The goal of using assertions is to let developers find the likely root cause of a bug more quickly. An assertion error should never be raised unless there's a bug in your program.

When to Use assert vs raise Python?

raise is typically used when you have detected an error condition or some condition does not satisfy. assert is similar but the exception is only raised if a condition is met. raise and assert have a different philosophy. There are many "normal" errors in code that you detect and raise errors.


2 Answers

Install your of function as sys.excepthook -- see the docs. Your function, if the second argument is AssertionError, can introspect to your heart's contents; in particular, through the third argument, the traceback, it can get the frame and exact spot in which the assert failed, getting the failing exception through the source or bytecode, the value of all relevant variables, etc. Module inspect helps.

Doing it in full generality is quite a piece of work, but depending on what constraints you're willing to accept in how you write your asserts it can be lightened substantially (e.g. restricting them to only local or global variables makes introspection easier than if nonlocal variables of a closure could be involved, and so forth).

like image 198
Alex Martelli Avatar answered Sep 28 '22 02:09

Alex Martelli


You can attach a message to an assert:

assert 6-(3*2), "always fails"

The message can also be built dynamically:

assert x != 0, "x is not equal to zero (%d)" % x

See The assert statement in the Python documentation for more information.

like image 35
Greg Hewgill Avatar answered Sep 28 '22 04:09

Greg Hewgill