Skip to content

Commit 1727520

Browse files
committed
-
1 parent 626529a commit 1727520

File tree

4 files changed

+41
-8
lines changed

4 files changed

+41
-8
lines changed

python_toolbox/caching/cached_property.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@
77
See its documentation for more details.
88
'''
99

10+
from python_toolbox import decorator_tools
1011
from python_toolbox import misc_tools
1112

1213

13-
class CachedProperty(misc_tools.OwnNameDiscoveringProperty):
14+
class CachedProperty(misc_tools.OwnNameDiscoveringDescriptor):
1415
'''
1516
A property that is calculated only once for an object, and then cached.
1617
@@ -39,7 +40,7 @@ def __init__(self, getter_or_value, doc=None, name=None):
3940
You may optionally pass in the name that this property has in the
4041
class; this will save a bit of processing later.
4142
'''
42-
misc_tools.OwnNameDiscoveringProperty.__init__(self, name=name)
43+
misc_tools.OwnNameDiscoveringDescriptor.__init__(self, name=name)
4344
self.getter = getter_or_value if callable(getter_or_value) \
4445
else lambda thing: getter_or_value
4546
self.__doc__ = doc or getattr(self.getter, '__doc__', None)
@@ -58,3 +59,11 @@ def __get__(self, obj, our_type=None):
5859
return value
5960

6061

62+
def __call__(self, method_function):
63+
'''
64+
Decorate method to use value of the `CachedProperty` as a context manager.
65+
'''
66+
def inner(same_method_function, self_obj, *args, **kwargs):
67+
with getattr(self_obj, self.get_our_name(self_obj)):
68+
return method_function(self_obj, *args, **kwargs)
69+
return decorator_tools.decorator(inner, method_function)

python_toolbox/misc_tools/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@
77
is_subclass, get_mro_depth_of_method, frange, getted_vars,
88
_ascii_variable_pattern, is_legal_ascii_variable_name,
99
is_magic_variable_name, get_actual_type, is_number, identity_function,
10-
do_nothing, OwnNameDiscoveringProperty, find_clear_place_on_circle
10+
do_nothing, OwnNameDiscoveringDescriptor, find_clear_place_on_circle
1111
)
1212
from . import name_mangling

python_toolbox/misc_tools/misc_tools.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,12 @@ def do_nothing(*args, **kwargs):
156156
pass
157157

158158

159-
class OwnNameDiscoveringProperty(object):
160-
''' '''
159+
class OwnNameDiscoveringDescriptor(object):
160+
'''A descriptor that can discover the name it's bound to on its object.'''
161+
161162
def __init__(self, name=None):
162163
'''
164+
Construct the `OwnNameDiscoveringDescriptor`.
163165
164166
You may optionally pass in the name that this property has in the
165167
class; this will save a bit of processing later.

test_python_toolbox/test_caching/test_cached_property.py

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55

66
import nose
77

8-
from python_toolbox.caching import (cache, CachedType,
9-
CachedProperty)
8+
from python_toolbox import context_managers
9+
10+
from python_toolbox.caching import cache, CachedType, CachedProperty
1011

1112

1213
def counting_func(self):
@@ -155,4 +156,25 @@ class C(object):
155156
)
156157

157158
assert C.undocced_property.__doc__ is None
158-
159+
160+
161+
def test_decorating():
162+
'''Test method-decorating functionality.'''
163+
164+
class A(object):
165+
reentrant_context_manager = CachedProperty(
166+
lambda self: context_managers.ReentrantContextManager()
167+
)
168+
169+
@reentrant_context_manager
170+
def my_method(self, x, y=3):
171+
return (x, y, self.reentrant_context_manager.depth)
172+
173+
a = A()
174+
175+
assert a.my_method(2) == (2, 3, 1)
176+
with a.reentrant_context_manager:
177+
assert a.my_method(y=7, x=8) == (8, 7, 2)
178+
with a.reentrant_context_manager:
179+
assert a.my_method(y=7, x=8) == (8, 7, 3)
180+

0 commit comments

Comments
 (0)