2006-10-27

assert hackable

I've got this real silly problem - assert is a reserved word in Python.

I can't define a function named assert because then I get a SyntaxError. At the moment I'm using _assert instead. It is ugly, and also, the _ is universally recognized as representing a private function or attribute so it's not a very good alternative.

I'll probably end up using assert_fact/retract_fact instead of assert/retract and that's fine. But, I just don't want to give up that easy. I did some experimenting and came up with this:

Kids! Don't try this at home! ;-)

This makes assert_hook catch ALL unhandled exceptions.

>>> import sys
>>> def assert_hook(t, val, tb):
... if "exceptions.AssertionError" in repr(t):
... ## call pyRete._assert(val)
... print "I caught %s and now, I'm gonna assert it!" % (val)
... else:
... ## this is not an AssertionError, re-raise Exception
... raise
>>> sys.excepthook = assert_hook
I just have to make sure that ALL Fact objects fail an Assertion
>>> class Fact(object):
... def __nonzero__(self):
... return False
Let's try it:
>>> foo = Fact()
>>> bar = { 'spam' : True, 'eggs' : False, }
>>> bar['spam']
True
>>> bar['foo']
Traceback (most recent call last):
...
KeyError: foo
Ok, so far, so good.
>>> assert foo
I caught <__main__.fact> and now, I'm gonna assert it!
Score! ;-)

2 kommentarer:

woolfel sa...

you're not the first person to come across reserved words issues. Before jdk1.4 came out, assert wasn't a key word. When jdk1.4 came out, all the programs that had assert stopped working, so lots of people had to refactor :)

JESS had to do a bit refactoring when jdk1.4 came out. I actually like using assertObject instead of just assert in sumatra. In my case though, I have assertFact and assertObject to differentiate internal fact representation and external objects.

Johan Lindberg sa...

Yeah, I guess it's quite common.

But in Python you can re-configure almost anything and I've grown accustomed to having this feature.

I guess the nature of assert makes it a not-very-good-idea to tamper with but I actually thought that the parser/compiler would be able to distinguish between when it's used as a statement and when it's used as a function.

Anyway, I'll stick with assert_fact