diff options
author | hut <hut@hut.pm> | 2017-07-16 06:28:25 +0200 |
---|---|---|
committer | hut <hut@hut.pm> | 2017-07-16 06:29:24 +0200 |
commit | c33844e98dab1759960f27dad1dfa4b3c3fead25 (patch) | |
tree | 86fac92c31b3ad66bafb221ebc73b260d5b28db5 | |
parent | f3243faa22ffd78ef654cd7ae4357a908408ac19 (diff) | |
download | ranger-c33844e98dab1759960f27dad1dfa4b3c3fead25.tar.gz |
ext.lazy_property: don't redefine resetter function
Without this change, binding a signal to a resetter function with a weak reference would delete the signal after it's called, because the function would be disconnected from the object and market for garbage collection. Also adapted the test cases to check for this problem. For example, commit 22ffd78ef654cd7ae4357a908408ac19 binds vcs__reset() to the signal "setopt.vcs_aware" with a weak ref. Because of that, the signal is only triggered the first time the setting is changed.
-rw-r--r-- | ranger/ext/lazy_property.py | 31 |
1 files changed, 16 insertions, 15 deletions
diff --git a/ranger/ext/lazy_property.py b/ranger/ext/lazy_property.py index ccd1586e..bb54bd5e 100644 --- a/ranger/ext/lazy_property.py +++ b/ranger/ext/lazy_property.py @@ -9,32 +9,30 @@ class lazy_property(object): # pylint: disable=invalid-name,too-few-public-meth """A @property-like decorator with lazy evaluation >>> class Foo: + ... counter = 0 ... @lazy_property ... def answer(self): - ... print("calculating answer...") - ... return 2*3*7 + ... Foo.counter += 1 + ... return Foo.counter >>> foo = Foo() >>> foo.answer - calculating answer... - 42 + 1 >>> foo.answer - 42 + 1 >>> foo.answer__reset() >>> foo.answer - calculating answer... - 42 + 2 >>> foo.answer - 42 + 2 Avoid interaction between multiple objects: >>> bar = Foo() >>> bar.answer - calculating answer... - 42 + 3 >>> foo.answer__reset() >>> bar.answer - 42 + 3 """ def __init__(self, method): @@ -46,11 +44,14 @@ class lazy_property(object): # pylint: disable=invalid-name,too-few-public-meth if obj is None: # to fix issues with pydoc return None - def reset_function(): - setattr(obj, self.__name__, self) - del obj.__dict__[self.__name__] # force "__get__" being called + reset_function_name = self.__name__ + "__reset" + + if not hasattr(obj, reset_function_name): + def reset_function(): + setattr(obj, self.__name__, self) + del obj.__dict__[self.__name__] # force "__get__" being called + obj.__dict__[reset_function_name] = reset_function - obj.__dict__[self.__name__ + "__reset"] = reset_function result = self._method(obj) obj.__dict__[self.__name__] = result return result |