"""Just the code from bonnet.py and python.py Skips documentation, (fauuoq,) comments and the two generators which exist purely to carry documentation, generator itself and generatorclass. $Id: justthecode.py,v 1.7 2005/02/12 17:07:23 eddy Exp $ """ # Well, OK, with minimal overhead def public(name): return name[:1] != '_' # != name[-1:] __magic__ = "__look_up Today's magic key, computed when this module gets loaded." def aslookup(object, *, **, magic=__magic__): try: return getattr(object, magic) except AttributeError: return lambda k, *, **, o=object: getattr(o, k) def within(*bases, **what, magic=__magic__, spawn=pnamespace, duldel=lambda : None): row = map(aslookup, bases) def getat(key, *, **, chain=row, dict=what): if key == '__dir__': bok = {} for nom in dict.keys(): bok[nom] = None for link in chain: try: more = link(key) except AttributeError: pass else: for nom in more: bok[nom] = None return filter(public, bok.keys()) try: return dict[key] except KeyError: pass for link in chain: try: return link(key) except AttributeError: pass raise AttributeError, key what[magic] = getat bok = {} def getit(key, *, **, bok=bok, fetch=getat): try: return bok[key] except KeyError: pass return fetch(key) bok.update({ magic: getit, '__lookups__': row, '__del__': duldel }) return spawn(getat), spawn(getit) del __magic__, pnamespace pythonic_protocols = ( 'lookups', 'self', 'data', 'wrap', 'magic', 'dir', 'bases', 'class', 'dict', 'init', 'len', 'del', 'nonzero', 'cmp', 'rcmp', 'getattr', 'setattr', 'delattr', 'getitem', 'setitem', 'delitem', 'getslice', 'setslice', 'delslice', 'neg', 'add', 'radd', 'sub', 'rsub', 'mul', 'rmul', 'div', 'rdiv', 'mod', 'rmod', 'divmod', 'rdivmod' ) def instance(*bases, class=None, **what, exclude=pythonic_protocols): if class is not None: what['__class__'] = class inst, shell = apply(within, bases, what) wrap, husk = within(inst, __self__=inst, __dict__={}, __del__=lambda : None) try: sweet = class.__wrap__ except AttributeError: def setit(key, val, *, **, bok=wrap.__dict__): bok[key] = val def delit(key, *, **, bok=wrap.__dict__): del bok[key] def grab(key, *, **, bok={ '__setattr__': setit, '__delattr__': delit }): try: return bok[key] except KeyError: raise AttributeError, key else: def grab(key, *, **, glean=aslookup(sweet), obj=wrap): def ans(*args, **what, meth=glean(key), self=obj): return apply(meth, (self,) + args, what) return ans husk.__lookups__.insert(0, grab) del husk try: schemes = class.__magic__ except AttributeError: pass else: for nom in schemes.__dir__: if nom not in exclude: try: obj = getattr(class, '__' + nom + '__') except AttributeError: pass else: getattr(schemes, nom)(obj, wrap, shell.__lookups__): def getit(key, *, **, book=wrap.__dict__): if key == '__dir__': return filter(public, book.keys()) try: return book[key] except KeyError: raise AttributeError, key def getat(key, *, **, obj=inst): if key != '__getattr__': try: return obj.__getattr__(key) except AttributeError: pass raise AttributeError, key shell.__lookups__.insert(0, getit) shell.__lookups__.append(getat) return inst, wrap instance wrap: instance __magic__: def wrap(funcs, inst, lookups): pass instance __wrap__: def __delattr__(self, key): del self.__dict__[key] def __setattr__(self, key, value): self.__dict__[key] = value instance data: instance __magic__: def data(given, inst, lookups): lookups.insert(0, aslookup(given)) __data__ = None instance method: instance __magic__: def method(funcs, inst, lookups): def fetch(key, *, **, meth=aslookup(funcs), obj=inst): if key == '__dir__': return meth(key) def ans(*args, **what, func=meth(key), self=obj): return apply(func, (self,) + args, what) return ans lookups.insert(0, fetch) instance __method__: def __init__(self): pass def __del__(self=None, *, **, naked=__self__.__del__): if self is None: naked() else: pass def __repr__(self): ans = self.__text(repr) self.__repr__ = lambda a=ans: a return ans def __str__(self): ans = self.__text(str) self.__str__ = lambda a=ans: a return ans def __text(self, text): form = 'object' try: k = self.__class__ except AttributeError: pass else: if self is not k: try: nom = k.__name__ except AttributeError: nom = text(k) else: try: nom = '%s.%s' % (k.__module__, nom) except AttributeError: pass form = nom + ' instance' return '<' + form + ' at ' + hex(id(self)) + '>' instance builder (method, data, wrap): instance __method__ (__method__,): def __attrseq(name, seq): row = [ None ] for b in seq: try: here = getattr(b, name) except AttributeError: pass else: for it in row: if it is here: break else: row.append(here) return row[1:] def __call__(self, *bases, **what, forbid=pythonic_protocols, glean=__attrseq, spawn=instance): sources = bases + (self,) row = glean('__magic__', sources) if len(row) > 1: names = what['__magic__'] = apply(within, tuple(row))[0] names = names.__dir__ elif row: names = row[0].__dir__ else: names = () for nom in names: assert nom not in forbid, 'scheme name and deep magic clash: ' + nom name = '__' + nom + '__' row = glean(name, sources) if len(row) > 1: what[name] = apply(within, tuple(row))[0] what.update({ '__bases__': bases, 'class': self }) return apply(spawn, bases, what) del __attrseq instance __magic__ (method.__magic__, data.__magic__, wrap.__magic__): pass def __getattr__(key, *, **, meths=aslookup(__method__)): def thod(*args, **what, func=meths(key)): return apply(func, (builder,) + args, what) return thod del pythonic_protocols builder class (method, data, wrap): instance __wrap__ (__wrap__,): def __get(self, magic): try: return self.__dict__[magic] except KeyError: pass try: ans = instance(getattr(self, magic)) except AttributeError: ans = instance() setattr(self, magic, ans) return ans def __delattr__(self, key, *, **): missing = 1 for it in ( '__data__', '__method__' ): try: delattr(self.__get(it), key) except AttributeError: pass else: missing = None if missing: raise AttributeError, key def __setattr__(self, key, val, *, **): if (key[:2] == '__' == key[-2:] and hasattr(self.__magic__, key[2:-2])): self.__dict__[key] = val elif callable(val): setattr(self.__get('__method__'), key, val) else: setattr(self.__get('__data__'), key, val) instance __method__ (__method__,): def __call__(self, *args, **what, spawn=instance): inst, wrap = spawn(class=self) apply(wrap.__init__, args, what) return wrap _rcs_log = """ $Log: justthecode.py,v $ Revision 1.7 2005/02/12 17:07:23 eddy Updated to match current state of bonnet and python Revision 1.6 2002/01/30 17:52:21 eddy Major revolution. Inlined post-within precursors in instance and simplified the resulting mess; added __wrap__ to carry wrapper methods from class; shunted class-specific magic (redirected attribute modification) into class, unburdening (gennie renamed as) builder. Moved all surviving precursors of instance from python.py to bonnet.py, emptying old junk from bonnet.py into novelty.py. Made the function defining a scheme receive the lookups list as third parameter; removed access to this list from instance wrappers; made wrapper's __dict__-based attribute modifier fallbacks come early, like __wrap__-derived kit, rather than late. Changed __meth__ to __method__, `generate' to `build', __schemes__ to __magic__. Re-documented plenty of stuff, revised web pages. Revision 1.5 2002/01/26 15:11:40 eddy tidy-up and simplification; moved instance early; next stop wyrm.py ... Revision 1.4 2002/01/23 04:02:34 eddy made __dir__ attribute universal; renamed initspace to extend; cleaned up scheme inheritance Revision 1.3 2002/01/22 19:16:24 eddy resync.d justthecode with python; tweaked some docs; untabified Revision 1.2 2002/01/22 18:58:13 eddy changed generators round to use __schemes__, with meth as just one such; added lazy.py Revision 1.1 2001/10/17 18:00:20 eddy added in all files previously missing from RCS Revision 1.3 2000/01/16 23:24:14 eddy Restored the missing what.update() in gennie (doh). Provided gennie and initspace with more configurability (for check.py). Revision 1.2 2000/01/15 18:15:01 eddy Re-built everyone using wrapped(). Initial Revision 1.1 2000/01/03 23:33:50 eddy """