diff options
Diffstat (limited to 'util/persistence.py.noargs')
-rw-r--r-- | util/persistence.py.noargs | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/util/persistence.py.noargs b/util/persistence.py.noargs new file mode 100644 index 0000000..bf982af --- /dev/null +++ b/util/persistence.py.noargs @@ -0,0 +1,75 @@ +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# + + +import sys + + +def is_persistent(item): + prop = item[1] + return type(prop) is property and \ + hasattr(prop.fget, 'decorator') and \ + prop.fget.decorator is PersistentProperty + + +class Persistent(type): + def __init__(cls, name, bases, dct): + # is_dirty + setattr(cls, '__dirty__', False) + + # properties + setattr(cls, '__properties__', filter(is_persistent, dct.iteritems())) + + super(Persistent, cls).__init__(name, bases, dct) + + +def PersistentProperty(function): + function.decorator = PersistentProperty + + keys = 'fset', 'fdel' + func_locals = {'doc':function.__doc__} + + def fgetter(obj, name, getter, fdef): + attr_name = '_' + obj.__class__.__name__ + '__' + name + if not hasattr(obj, attr_name): + setattr(obj, attr_name, fdef(obj)) + return getter(obj) + + def fsetter(obj, name, setter, value): + setattr(obj, '__dirty__', True) + return setter(obj, value) + + def probe_function(frame, event, arg): + if event == 'return': + locals = frame.f_locals + func_locals.update(dict((k,locals.get(k)) for k in keys)) + + if locals.has_key('fset'): + func_locals['fset'] = lambda obj, value : fsetter(obj, function.__name__, locals['fset'], value) + + if locals.has_key('fdef'): + f = lambda obj : fgetter(obj, function.__name__, locals['fget'], locals['fdef']) + else: + f = lambda obj : fgetter(obj, function.__name__, locals['fget'], lambda x : None) + f.decorator = PersistentProperty # tag the getter + func_locals['fget'] = f + + sys.settrace(None) + return probe_function + sys.settrace(probe_function) + function() + return property(**func_locals) + + |