#!/usr/bin/python """ Test Case demonstrating bug in _c_htmltext.c """ from quixote import _c_htmltext from quixote import _py_htmltext c_htmltext = _c_htmltext.htmltext("%(This)s is _c_htmltext.htmltext().") py_htmltext = _py_htmltext.htmltext("%(This)s is _py_htmltext.htmltext().") LOG_ACCESSES = False #True class DictEmulator(object): """ This is a very contrived example... It would be pointless in the real world. It's only purpose is to ACT like a dictionary, without actually BEING one. (Even though it uses one internally) """ def __init__(self): self._dict = {} def __getattribute__(self, attr): log("%r.%s accessed" % (self, attr)) if attr.startswith('_'): return object.__getattribute__(self, attr) else: return object.__getattribute__(self, '_dict').__getattribute__(attr) def __getitem__(self, key): log("%r.__getitem__(%r) called" % (self, key)) return self._dict[key] def __setitem__(self, key, value): log("%r.__setitem__(%r,%r) called" % (self, key, value)) self._dict[key] = value def __contains__(self, item): return item in self._dict def __len__(self): return len(self._dict) class DictSubclass(dict): def __getattribute__(self, attr): log("%r.%s accessed" % (self, attr)) return dict.__getattribute__(self, attr) def __getitem__(self, key): log("%r.__getitem__(%r) called" % (self, key)) return dict.__getitem__(self, key) def __setitem__(self, key, value): log("%r.__setitem__(%r,%r) called" % (self, key, value)) dict.__setitem__(self, key, value) def log(v): if LOG_ACCESSES: print " (((%s)))" % v # Setting up the objects for the test. # A dict, a subclass of dict, and something # that emulates (and wraps) a dict print "Now initializing the dict" dict_dict = {} dict_dict['This'] = "This string or string-like instance" print "Done\n\n" print "Now initializing the DictSubclass" dict_subclass = DictSubclass() dict_subclass['This'] = "This string or string-like instance" print "Done\n\n" print "Now initializing the DictEmulator" dict_emulator = DictEmulator() dict_emulator['This'] = "This string or string-like instance" print "Done\n\n" # Now I'm demonstrating that all three # pass reasonable tests that should be # expected of a dict-like objects print "'Exercising' the dict-like objects" for d in (dict_dict, dict_subclass, dict_emulator): print "OBJECT IN TEST:", d.__class__.__name__ print "keys: ", d.keys() print "values: ", d.values() print "items: ", d.items() print "__contains__: ", 'This' in d print "__getitem__: ", d['This'] print "__len__: ", len(d) print '' print "Done\n\n" # And now I'll demonstrate the discrepancy between # _c_htmltext.c and _py_htmltext.py # To see the output that the following comments mention # set LOG_ACCESSES = True at the top of the script. print "Now using dict as format arg to %r" % py_htmltext print py_htmltext % dict_dict # <--- Notice in the output that items() was accessed print "Done\n\n" print "Now using dict as format arg to %r" % c_htmltext print c_htmltext % dict_dict # <--- Notice in the output that items() was NOT accessed print "Done\n\n" print "Now using DictSubclass as format arg to %r" % py_htmltext print py_htmltext % dict_subclass # <--- Notice in the output that items() was accessed print "Done\n\n" print "Now using DictSubclass as format arg to %r" % c_htmltext print c_htmltext % dict_subclass # <--- Notice in the output that items() was NOT accessed print "Done\n\n" print "Now using DictEmulator as format arg to %r" % py_htmltext print py_htmltext % dict_emulator # <--- Notice in the output that items() was accessed print "Done\n\n" print "Now using DictEmulator as format arg to %r" % c_htmltext print c_htmltext % dict_emulator # <--- This will bomb out on a KeyError! print "Done\n\n"