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

Terry Reedy tjreedy at udel.edu
Fri Apr 29 01:24:37 CEST 2011


On 4/28/2011 8:27 AM, Tarek Ziadé wrote:

 >> On 28/04/2011 09:34, Terry Reedy wrote:

 >>> 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.
 >
 > But it does affect the behaviour at the end: when the code has a bug,

That is just what I just said: 'unless the code has a bug'.

 > then the way the code works is affected and differs depending if -O is
 > used.

As long as Python has flags that affect code and its execution, the 
stdlib should be tested with them.

 > Let me take an example:
 >
 > bucket = []
 >
 > def add(stuff):
 >      bucket.append(stuff)
 >
 > def purge_and_do_something():
 >      bucket.clear()
 >      assert len(bucket) == 0
 >      ... do something by being sure the bucket is empty ...
 >
 >
 > here, we could say assert is legitimate, as it just checks a
 > post-condition.

No, not legitimate: the .clear() post-condition check should be in 
.clear(), not in code that uses it.

 > But this code is not thread-safe and if it's run via
 > several threads, some code could add something in the bucket while
 > purge() check for the assertion.

It is, or should be, well-known that concurrency, in general, makes 
programs non-deterministic (which is to say, potentially buggy relative 
to expectations). Purge needs a write-lock (that still allows .clear() 
to run).

 > My point is that I do not understand why there are assert calls to
 > check post-conditions.

Assert are inline unittests that long predate the x-unit modules for 
various languages. One advantage over separate test suites is that they 
test that the function works properly not only with the relatively few 
inputs in most test suites but also with all inputs in the integration 
and acceptance tests and, if left in place, in actual use.

 > Moreover, why -O and -OO are removing assertions in that case ?

A polynomial-time verification function may still take awhile.  For 
instance, is_sorted_version_of(input, output) has to verify both that 
output is sorted (easy) and that it is a permutation of the input 
(harder). So you might like it optionally gone in production but still 
present in source and optionally present in production where speed is 
not critical.

 > 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...

I use asserts to test my custom test functions that they pass obviously 
good functions and fail intentionally bad functions with the proper 
error message. Not dead at all, especially when I 'refactor' (fiddle 
with) the test functin code. Of course, I could replace then with if (): 
raise or print, by why?

---
Terry Jan Reedy





More information about the Python-ideas mailing list