[Python-ideas] [Python-Dev] the role of assert in the standard library ?

Steven D'Aprano steve at pearwood.info
Thu Apr 28 15:49:40 CEST 2011


Tarek Ziadé wrote:

> From what I understood so far, a line with an assert should be
> considered as a dead code if we want the code to behave always the
> same way. I remove dead code in my code...

No. There's a difference between dead code (code that cannot be reached) 
and asserts. An assert is a statement of confidence:

"I'm sure that this assertion is true, but I'm not 100% sure, because 
bugs do exist. But since I'm *nearly* 100% sure, it is safe to optimize 
the assertions away, *if* you are brave enough to run with the -O flag."

If you've ever written the typical defensive pattern:

if a:
    do_this()
elif b:
    do_that()
elif c:
    do_something_else()
else:
    # This can never happen.
    raise RuntimeError('unexpected error')

then you have a perfect candidate for an assertion:

assert any([a, b, c], 'unexpected error')


You know what they say about things that can never happen: they *do* 
happen, more often than you like. An assertion is to check for things 
that can never happen. Since it can't happen, it's safe to optimize it 
away and not perform the check. But since things that can't happen do 
happen (due to logic errors and the presence of unexpected bugs), it's 
better to generate a failure immediately, where you perform the check, 
rather than somewhere else far distant from the problem, or worse, 
returning the wrong result.

Assertions are a case of practicality beats purity: in a perfect world, 
we'd always be 100% confident that our code was bug-free and free of any 
logic errors, and that our assumptions were perfectly correct. But in 
the real world, we can't always be quite so sure, and asserts cover that 
middle ground where we're *almost* sure about a condition, but not 
entirely. Or perhaps we're merely paranoid. Either way, asserts should 
never be something you *rely* on (e.g. checking user input).

Let me give you a real world example: I have some code to calculate the 
Pearson's Correlation Coefficient, r. At the end of the function, just 
before returning, I assert -1 <= r <= 1. I've run this function 
thousands of times, possibly tens of thousands, over periods of months, 
without any problems. Last week I got an assertion error: r was 
something like 1.00000000000000001 (or thereabouts).

So now I know there's a bug in my code. (Unfortunately, not *where* it 
is.) Without the assert, I wouldn't know, because that r would likely 
have been used in some larger calculation, without me ever noticing that 
it can be out of range.




-- 
Steven




More information about the Python-ideas mailing list