When Python asserts don't
Bewildered why error conditions are breezing right past the 'assert' statements you sprinkled through your Python script? Maybe you made the same basic mistake I did ...
'assert's are a good thing. They allow you to passively detect error conditions in your code, rather than having to be actively suspicious of your program state at any point. However, I recently came across a case where error states were cropping up, seemingly slipping by the asserts I'd carefully flanked my code with.
The situation was this: I was parsing some 1000 files by using regular expressions. As the files weren't entirely consistently formatted, I was using asserts to test whether the regex was failing to match:
theMatch = re.search (" ([0-9\-\.\:]+)$", theFileLines[-1])
assert (theMatch != None, "date does not match format")
The problem here is that the format of the assert function is not:
assert (<test>, <message>)
but:
assert <test>, <message>
In some languages (like RealBasic) these two forms are interchangable. Not so in Python in this case. The assert sees the bracketed argument list as a single unit that it uses as the test. The argument list is interpreted as a tuple, and as it is non-empty, it evaluates to true. Thus, the assertion never fails.
Obviously, the solution is to use the correct form and so the above code becomes:
theMatch = re.search (" ([0-9\-\.\:]+)$", theFileLines[-1])
assert theMatch != None, "date does not match format"
An additional quick Python tip for free: in the same session, I kept getting
a cryptic float division error, when I divided two floating point numbers
together. After much sweating, it turns out that when you try to divide zero
by a float, Python generates this error by throwing ZeroDivisionError: float
division. Depending on how you capture the error (I was trapping exceptions
and printing off the error messages), the informative ZeroDivisionError can
be cut off, leaving the less-than-informative float message. The fact that a
float is involved is irrelevant. The similiar situation with integer has the
much more helpful message integer division or modulo by zero.

