diff options
Diffstat (limited to 'libbe/properties.py')
-rw-r--r-- | libbe/properties.py | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/libbe/properties.py b/libbe/properties.py index a8e89fb..9292ad7 100644 --- a/libbe/properties.py +++ b/libbe/properties.py @@ -26,12 +26,15 @@ and for more information on decorators. """ +import types import unittest - class ValueCheckError (ValueError): def __init__(self, name, value, allowed): - msg = "%s not in %s for %s" % (value, allowed, name) + action = "in" # some list of allowed values + if type(allowed) == types.FunctionType: + action = "allowed by" # some allowed-value check function + msg = "%s not %s %s for %s" % (value, action, allowed, name) ValueError.__init__(self, msg) self.name = name self.value = value @@ -258,12 +261,29 @@ def primed_property(primer, initVal=None): return funcs return decorator -def change_hook_property(hook): +def change_hook_property(hook, mutable=False): """ Call the function hook(instance, old_value, new_value) whenever a value different from the current value is set (instance is a a reference to the class instance to which this property belongs). - This is useful for saving changes to disk, etc. + This is useful for saving changes to disk, etc. This function is + called _after_ the new value has been stored, allowing you to + change the stored value if you want. + + If mutable=True, store a string-representation of the old_value + for use in comparisions, since + + >>> a = [] + >>> b = a + >>> b.append(1) + >>> a + [1] + >>> a==b + True + + The string-value-changed test may miss the first write, since + there will not have been an opportunity to cache a string version + of the old value. """ def decorator(funcs): if hasattr(funcs, "__call__"): @@ -273,9 +293,23 @@ def change_hook_property(hook): name = funcs.get("name", "<unknown>") def _fset(self, value): old_value = fget(self) + fset(self, value) + change_detected = False if value != old_value: + change_detected = True + elif mutable == True: + if True: #hasattr(self, "_change_hook_property_mutable_cache_%s" % name): + # compare cached string with new value + #old_string = getattr(self, "_change_hook_property_mutable_cache_%s" % name) + old_string = "dummy" + #print "comparing", name, "mutable strings", old_string, repr(value) + if repr(value) != old_string: + change_detected = True + #print "testing", name, "change hook property", change_detected, value + if change_detected: hook(self, old_value, value) - fset(self, value) + if mutable == True: # cache the new value for next time + setattr(self, "_change_hook_property_mutable_cache_%s" % name, repr(value)) funcs["fset"] = _fset return funcs return decorator |