How can I make my assertions smarter?

Jesse Sweeney jesse at student.usyd.edu.au
Tue Nov 2 03:06:23 CET 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