How can I make my assertions smarter?

Michael Hudson mwh21 at
Mon Nov 1 14:35:53 CET 1999

Stuart Hungerford <stuart.hungerford at> writes:

> Hi all,
> I'm using some simple functions to implement crude precondition,
> postcondition and invariant checking in Python classes.
> (Tim: please be gentle ;-)
> Is there some neat way to wrap these tests up so I can print any
> code expression that fails, e.g:
>      Precondition failed line 42: spoon.shape == 'bent'
> which would appear at line 42 of as
>      pre(spoon.shape == 'bent')

Hmm... tricky.

Something like this might work (tho' not with python -O, not that that
should be a problem).

chuck it in a file called "". It will have problems with line
continutations & stuff, but I did just make it up on the spot (well,
about half an hour of spot; must now do something of some use).

class PreconditionViolation(AssertionError):
    def __init__(self,why):

def pre(cond):
    if cond:
        raise ""
        import sys
        frame = sys.exc_traceback.tb_frame.f_back
        lineno = frame.f_lineno
        filename = frame.f_code.co_filename    
        import re
        file = open(filename)
        for i in range(lineno):
            line = file.readline()
        match = re.match("\W*(pre\.)?pre\((.*)\);?\W*$",line)
        if match is not None:
            line =
            import string
            line = string.strip(line)
        line = "<not found>"
    line = "line %d of %s: %s"%(lineno,filename,line)
    raise PreconditionViolation, line
def checked_sqrt(x):
    from math import sqrt
    return sqrt(x)
if __name__=='__main__':
    print checked_sqrt(2)
    print checked_sqrt(-1)

then `python' gives:

Traceback (innermost last):
  File "", line 39, in ?
    print checked_sqrt(-1)
  File "", line 34, in checked_sqrt
  File "", line 30, in pre
    raise PreconditionViolation, line
__main__.PreconditionViolation: line 34 of x>=0

but, really, what's wrong with asserts?

Another approach would be to poke around with frame.f_lasti and
decompile the bytecode (!).

> I can see how to use environment variables or global variables to
> selectively enable precondtions etc, although any hints for doing that
> would be appreciated too.

That should be pretty straightforward.

> Thanks in advance,
> Stu


More information about the Python-list mailing list