"assert" annoyance

P

Paul Rubin

So I have some assert statements in my code to verify the absence of
some "impossible" conditions. They were useful in debugging and of
course I left them in place for "real" runs of the program. Umpteen
hours into a run, an assertion failed, and of course since failure
was "impossible", I didn't catch the exception so the whole program
crashed. I don't know what I'd have done with the exception anyway,
since it would have had to be caught at an outer scope where the
data I cared about was no longer around, or else I'd have had to
predict in advance what I needed to examine and pass that as a
an arg to the assert statement.

What I really want is for any assertion failure, anywhere in the
program, to trap to the debugger WITHOUT blowing out of the scope
where the failure happened, so I can examine the local frame. That
just seems natural, but I don't see an obvious way to do it. Am I
missing something? I guess I could replace all the assertions with
function calls that launch pdb, but why bother having an assert
statement?
 
M

Miles

What I really want is for any assertion failure, anywhere in the
program, to trap to the debugger WITHOUT blowing out of the scope
where the failure happened, so I can examine the local frame. That
just seems natural, but I don't see an obvious way to do it.

You could run the entire program through pdb:
----
#!/usr/bin/env python -m pdb

print "Hello!"
assert False
print "...world!"
----
 
E

Evan Klitzke

You could run the entire program through pdb:
----
#!/usr/bin/env python -m pdb

print "Hello!"
assert False
print "...world!"
----

You can only pass one argument to a command that you invoke with the
shebang sequence, so this won't work the way you wrote it.
 
M

Miles

You can only pass one argument to a command that you invoke with the
shebang sequence, so this won't work the way you wrote it.

It actually does work on my system (OS X); I didn't realize it wasn't
portable.
 
T

Thomas Heller

Paul said:
So I have some assert statements in my code to verify the absence of
some "impossible" conditions. They were useful in debugging and of
course I left them in place for "real" runs of the program. Umpteen
hours into a run, an assertion failed, and of course since failure
was "impossible", I didn't catch the exception so the whole program
crashed. I don't know what I'd have done with the exception anyway,
since it would have had to be caught at an outer scope where the
data I cared about was no longer around, or else I'd have had to
predict in advance what I needed to examine and pass that as a
an arg to the assert statement.

What I really want is for any assertion failure, anywhere in the
program, to trap to the debugger WITHOUT blowing out of the scope
where the failure happened, so I can examine the local frame. That
just seems natural, but I don't see an obvious way to do it. Am I
missing something? I guess I could replace all the assertions with
function calls that launch pdb, but why bother having an assert
statement?

http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65287

Thomas
 
E

Evan Klitzke

It actually does work on my system (OS X); I didn't realize it wasn't
portable.

This sort of surprised me (in a good way), since I just took the one
argument rule for granted. It's always bugged me that I couldn't do,
say, #!/usr/bin/env python -O. So it's nice to see that OS X splits
the arguments, even if this isn't completely portable! I did some
research on this and it looks like a few other Unices do it too. If
anyone is interested, there's a table documenting the behavior of
different systems at
http://www.in-ulm.de/~mascheck/various/shebang/#results

Maybe I should start using a Mac ;-)
 
B

Ben Finney

Paul Rubin said:
So I have some assert statements in my code to verify the absence of
some "impossible" conditions. They were useful in debugging and of
course I left them in place for "real" runs of the program. Umpteen
hours into a run, an assertion failed, and of course since failure
was "impossible", I didn't catch the exception so the whole program
crashed.

This is exactly the sort of check which is best done as unit
tests. The program has no 'assert' cruft in it, and the tests can be
as comprehensive as needed without having any impact on the actual
running program.
 
P

Paul Rubin

Ben Finney said:
This is exactly the sort of check which is best done as unit
tests. The program has no 'assert' cruft in it, and the tests can be
as comprehensive as needed without having any impact on the actual
running program.

I don't understand what you're trying to say here. The code was
tested before I ran it with real data. The asserts triggered because
there was a real problem, so removing them would not have been the
right thing to do. On the other hand, the code had already been
tested without discovering the problem. The problem could not have
been found without running the program for hours, not something one
would normally do in a unit test, and also it involved an unexpected
error from a remote program (a 3GB process had run out of memory).
Unit tests are not a magic wand that discover every problem that a
program could possibly have.
 
D

Dave Baum

Paul Rubin said:
What I really want is for any assertion failure, anywhere in the
program, to trap to the debugger WITHOUT blowing out of the scope
where the failure happened, so I can examine the local frame. That
just seems natural, but I don't see an obvious way to do it. Am I
missing something? I guess I could replace all the assertions with
function calls that launch pdb, but why bother having an assert
statement?

I tend to run my programs with a -i option:

python -i foo.py

Then if an exception occurs, I can do:

import pdb
pdm.pm()

and have a debug session at the point where the exception was raised.
The "-i" shouldn't interfere with sys.argv since it is before the python
file.

Another option would be for your program to do something like:

try:
# put your code here
except:
import sys
import pdb
pdb.post_mortem(sys.exc_info()[2])


If an exception is raised, the debugger will be started using the
appropriate traceback. (You don't need to import sys and pdb in the
except block if they have already been imported.)


Dave
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

How can this assert() ever trigger? 8
Assertion Error 2
doctest annoyance/puzzle 2
Place Assert in Exception 19
assert question 4
assert in C 73
Generics annoyance 18
if(!p) { assert(false); return NULL; } ... ? 14

Members online

Forum statistics

Threads
473,994
Messages
2,570,222
Members
46,810
Latest member
Kassie0918

Latest Threads

Top