Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/util/persistence.py.noargs
diff options
context:
space:
mode:
Diffstat (limited to 'util/persistence.py.noargs')
-rw-r--r--util/persistence.py.noargs75
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)
+
+