a patch, it got even tidier ;-) - no more _tidy() calls, all automated. On Monday 20 August 2007 16:41:30 svilen wrote: > a suggestion about _list_decorators() and similar. > they can be easily made into classes, i.e. non dynamic (and > overloadable/patchable :-). > > class _list_decorators( object):
--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~----------~----~----~----~------~----~------~--~---
Index: sqlalchemy/orm/collections.py =================================================================== --- sqlalchemy/orm/collections.py (revision 3375) +++ sqlalchemy/orm/collections.py (working copy) @@ -746,7 +749,7 @@ pass return wrapper -def __set(collection, item, _sa_initiator=None): +def _set(collection, item, _sa_initiator=None): """Run set events, may eventually be inlined into decorators.""" if _sa_initiator is not False and item is not None: @@ -754,7 +757,7 @@ if executor: getattr(executor, 'fire_append_event')(item, _sa_initiator) -def __del(collection, item, _sa_initiator=None): +def _del(collection, item, _sa_initiator=None): """Run del events, may eventually be inlined into decorators.""" if _sa_initiator is not False and item is not None: @@ -762,17 +765,28 @@ if executor: getattr(executor, 'fire_remove_event')(item, _sa_initiator) -def _list_decorators(): +def _tidy_(fn, base): + fn._sa_instrumented = True + fn.__doc__ = getattr( base, fn.__name__).__doc__ + return fn + +def _tider( func, base): + def f( fn): return _tidy_( func(fn), base) + return f + +def _get_decorators( d, base): + skip = '__module__', '__doc__', + return dict( (k,_tider(v,base)) for k,v in d.iteritems() if k not in skip ) + + +class _list_decorators( object):#def _list_decorators(): """Hand-turned instrumentation wrappers that can decorate any list-like class.""" - def _tidy(fn): - setattr(fn, '_sa_instrumented', True) - fn.__doc__ = getattr(getattr(list, fn.__name__), '__doc__') def append(fn): def append(self, item, _sa_initiator=None): - # FIXME: example of fully inlining __set and adapter.fire + # FIXME: example of fully inlining _set and adapter.fire # for critical path if _sa_initiator is not False and item is not None: executor = getattr(self, '_sa_adapter', None) @@ -780,21 +794,18 @@ executor.attr.fire_append_event(executor._owner(), item, _sa_initiator) fn(self, item) - _tidy(append) return append def remove(fn): def remove(self, value, _sa_initiator=None): fn(self, value) - __del(self, value, _sa_initiator) - _tidy(remove) + _del(self, value, _sa_initiator) return remove def insert(fn): def insert(self, index, value): - __set(self, value) + _set(self, value) fn(self, index, value) - _tidy(insert) return insert def __setitem__(fn): @@ -802,8 +813,8 @@ if not isinstance(index, slice): existing = self[index] if existing is not None: - __del(self, existing) - __set(self, value) + _del(self, existing) + _set(self, value) fn(self, index, value) else: # slice assignment requires __delitem__, insert, __len__ @@ -830,114 +841,101 @@ len(rng))) for i, item in zip(rng, value): self.__setitem__(i, item) - _tidy(__setitem__) return __setitem__ def __delitem__(fn): def __delitem__(self, index): if not isinstance(index, slice): item = self[index] - __del(self, item) + _del(self, item) fn(self, index) else: # slice deletion requires __getslice__ and a slice-groking # __getitem__ for stepped deletion # note: not breaking this into atomic dels for item in self[index]: - __del(self, item) + _del(self, item) fn(self, index) - _tidy(__delitem__) return __delitem__ def __setslice__(fn): def __setslice__(self, start, end, values): for value in self[start:end]: - __del(self, value) + _del(self, value) for value in values: - __set(self, value) + _set(self, value) fn(self, start, end, values) - _tidy(__setslice__) return __setslice__ def __delslice__(fn): def __delslice__(self, start, end): for value in self[start:end]: - __del(self, value) + _del(self, value) fn(self, start, end) - _tidy(__delslice__) return __delslice__ def extend(fn): def extend(self, iterable): for value in iterable: self.append(value) - _tidy(extend) return extend def pop(fn): def pop(self, index=-1): item = fn(self, index) - __del(self, item) + _del(self, item) return item - _tidy(pop) return pop - l = locals().copy() - l.pop('_tidy') - return l + _funcs = _get_decorators( locals(), list ) + + def __new__( klas): + return klas._funcs -def _dict_decorators(): +class _Unspecified: pass + +class _dict_decorators( object): """Hand-turned instrumentation wrappers that can decorate any dict-like mapping class.""" - def _tidy(fn): - setattr(fn, '_sa_instrumented', True) - fn.__doc__ = getattr(getattr(dict, fn.__name__), '__doc__') - - Unspecified=object() def __setitem__(fn): def __setitem__(self, key, value, _sa_initiator=None): if key in self: - __del(self, self[key], _sa_initiator) - __set(self, value, _sa_initiator) + _del(self, self[key], _sa_initiator) + _set(self, value, _sa_initiator) fn(self, key, value) - _tidy(__setitem__) return __setitem__ def __delitem__(fn): def __delitem__(self, key, _sa_initiator=None): if key in self: - __del(self, self[key], _sa_initiator) + _del(self, self[key], _sa_initiator) fn(self, key) - _tidy(__delitem__) return __delitem__ def clear(fn): def clear(self): for key in self: - __del(self, self[key]) + _del(self, self[key]) fn(self) - _tidy(clear) return clear def pop(fn): - def pop(self, key, default=Unspecified): + def pop(self, key, default=_Unspecified): if key in self: - __del(self, self[key]) - if default is Unspecified: + _del(self, self[key]) + if default is _Unspecified: return fn(self, key) else: return fn(self, key, default) - _tidy(pop) return pop def popitem(fn): def popitem(self): item = fn(self) - __del(self, item[1]) + _del(self, item[1]) return item - _tidy(popitem) return popitem def setdefault(fn): @@ -947,7 +945,6 @@ return default else: return self.__getitem__(key) - _tidy(setdefault) return setdefault if sys.version_info < (2, 4): @@ -956,12 +953,11 @@ for key in other.keys(): if key not in self or self[key] is not other[key]: self[key] = other[key] - _tidy(update) return update else: def update(fn): - def update(self, __other=Unspecified, **kw): - if __other is not Unspecified: + def update(self, __other=_Unspecified, **kw): + if __other is not _Unspecified: if hasattr(__other, 'keys'): for key in __other.keys(): if key not in self or self[key] is not __other[key]: @@ -973,60 +969,48 @@ for key in kw: if key not in self or self[key] is not kw[key]: self[key] = kw[key] - _tidy(update) return update - l = locals().copy() - l.pop('_tidy') - l.pop('Unspecified') - return l + _funcs = _get_decorators( locals(), dict ) + + def __new__( klas): + return klas._funcs -def _set_decorators(): +class _set_decorators( object): """Hand-turned instrumentation wrappers that can decorate any set-like sequence class.""" - def _tidy(fn): - setattr(fn, '_sa_instrumented', True) - fn.__doc__ = getattr(getattr(set, fn.__name__), '__doc__') - - Unspecified=object() - def add(fn): def add(self, value, _sa_initiator=None): - __set(self, value, _sa_initiator) + _set(self, value, _sa_initiator) fn(self, value) - _tidy(add) return add def discard(fn): def discard(self, value, _sa_initiator=None): if value in self: - __del(self, value, _sa_initiator) + _del(self, value, _sa_initiator) fn(self, value) - _tidy(discard) return discard def remove(fn): def remove(self, value, _sa_initiator=None): if value in self: - __del(self, value, _sa_initiator) + _del(self, value, _sa_initiator) fn(self, value) - _tidy(remove) return remove def pop(fn): def pop(self): item = fn(self) - __del(self, item) + _del(self, item) return item - _tidy(pop) return pop def clear(fn): def clear(self): for item in list(self): self.remove(item) - _tidy(clear) return clear def update(fn): @@ -1034,7 +1018,6 @@ for item in value: if item not in self: self.add(item) - _tidy(update) return update __ior__ = update @@ -1042,7 +1025,6 @@ def difference_update(self, value): for item in value: self.discard(item) - _tidy(difference_update) return difference_update __isub__ = difference_update @@ -1055,7 +1037,6 @@ self.remove(item) for item in add: self.add(item) - _tidy(intersection_update) return intersection_update __iand__ = intersection_update @@ -1068,14 +1049,12 @@ self.remove(item) for item in add: self.add(item) - _tidy(symmetric_difference_update) return symmetric_difference_update __ixor__ = symmetric_difference_update - l = locals().copy() - l.pop('_tidy') - l.pop('Unspecified') - return l + _funcs = _get_decorators( locals(), set ) + def __new__( klas): + return klas._funcs class InstrumentedList(list):