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

Michael Foord fuzzyman at voidspace.org.uk
Thu Apr 28 12:27:14 CEST 2011


On 28/04/2011 09:34, Terry Reedy wrote:
> On 4/28/2011 3:54 AM, Tarek Ziadé wrote:
>> Hello
>>
>> I removed some assert calls in distutils some time ago because the
>> package was not behaving correctly when people were using Python with
>> the --optimize flag. In other words, assert became a full part of the
>> code logic and removing them via -O was changing the behavior.
>>
>> In my opinion assert should be avoided completely anywhere else than
>> in the tests. If this is a wrong statement, please let me know why :)
>
> My understanding is that assert can be used in production code but 
> only to catch logic errors by testing supposed invariants or 
> postconditions. It should not be used to test usage errors, including 
> preconditions. In other words, assert presence or absence should not 
> affect behavior unless the code has a bug.

Agreed. We should ideally have buildbots doing test runs with -O and 
-OO. R. David Murray did a lot of work a year ago (or so) to ensure the 
test run passes with -OO but it easily degrades..

There are a couple of asserts in unittest (for test discovery) but I 
only use them to provide failure messages early. The functionality is 
unchanged (and tests still pass) with -OO.

All the best,

Michael Foord
>
>> So, I grepped the stdlib for assert calls, and I have found 177 of
>> them and many of them are making Python acts differently depending on
>> the -O flag,
>>
>> Here's an example on a randomly picked assert in the threading module:
>
> This, to me is wrong:
>
>    def __init__(self, group=None, target=None, name=None,
>                  args=(), kwargs=None, verbose=None):
>         assert group is None, "group argument must be None for now"
>
> That catches a usage error and should raise a ValueError.
>
> This
>
>     def _wait(self, timeout):
>         if not self._cond.wait_for(lambda : self._state != 0, timeout):
>             #timed out.  Break the barrier
>             self._break()
>             raise BrokenBarrierError
>         if self._state < 0:
>             raise BrokenBarrierError
>         assert self._state == 1
>
> appears to be, or should be, a test of a postcondition that should 
> *always* be true regardless of usage.
>
>


-- 
http://www.voidspace.org.uk/

May you do good and not evil
May you find forgiveness for yourself and forgive others
May you share freely, never taking more than you give.
-- the sqlite blessing http://www.sqlite.org/different.html



More information about the Python-Dev mailing list