How can I make my assertions smarter?
Jesse Sweeney
jesse at student.usyd.edu.au
Mon Nov 1 21:06:23 EST 1999
On 01 Nov 1999 16:55:02 +0100, mlh at vier.idi.ntnu.no (Magnus L. Hetland) wrote:
[ Stuart, hungering for preconditions ]
>How about using (assuming that you won't use assert):
>
> pre("spoon.shape == 'bent'")
>
>And then using eval() in your code? Like...
>
> def pre(condition):
> if not eval(condition):
> raise "Precondition Failure", condition
>
>Pretty simple, IMO...
Simple? Yes. Works? No. <wink>
The problem is that pre's locals aren't the same as the locals in the function
from which pre is being called, so you run into problems like this one:
>>> def pre(condition):
if not eval(condition):
raise "Precondition Failure", condition
>>> def f(a, b):
pre('a == b')
# Some more stuff
>>> f(4, 4)
Traceback (innermost last):
File "<pyshell#8>", line 1, in ?
f(4, 4)
File "<pyshell#6>", line 2, in f
pre('a == b')
File "<pyshell#2>", line 2, in pre
if not eval(condition):
File "<string>", line 0, in ?
NameError: a
You can fix that by passing locals() and globals() to pre(), or by using an ugly
hack like the one used to find the name of the calling function, if that's too
much typing:
import sys
def upglobals():
try:
1/0
except ZeroDivisionError:
return sys.exc_info()[2].tb_frame.f_back.f_back.f_globals
def uplocals():
try:
1/0
except ZeroDivisionError:
return sys.exc_info()[2].tb_frame.f_back.f_back.f_locals
def pre(condition, locals=None, globals=None):
if not locals:
locals = uplocals()
if not globals:
globals = upglobals()
if not eval(condition, locals, globals):
raise "Precondition Failure", condition
Then, we have:
>>> f(3, 4)
Traceback (innermost last):
File "<pyshell#9>", line 1, in ?
f(3, 4)
File "<pyshell#8>", line 2, in f
pre('a == b')
File "<pyshell#6>", line 7, in pre
raise "Precondition Failure", condition
Precondition Failure: a == b
>>> f(4, 4)
>>>
A wiser man than me once said "It is easier to write an incorrect program than
understand a correct one." <wink>
Cheers, Jesse.
More information about the Python-list
mailing list