Complete the cachedproperty descriptor protocol
Refactor some parts of the cachedproperty property descriptor (renaming attributes to the standard names used in descriptor objects) and add on the __set__ and __delete__ methods to comply with the full descriptor protocol. Change-Id: I1f1e8e301271c060d14acc3a77c094dabd120f16
This commit is contained in:
@@ -180,30 +180,37 @@ class cachedproperty(object):
|
|||||||
those methods into properties that will be cached in the instance (avoiding
|
those methods into properties that will be cached in the instance (avoiding
|
||||||
repeated creation checking logic to do the equivalent).
|
repeated creation checking logic to do the equivalent).
|
||||||
"""
|
"""
|
||||||
def __init__(self, wrapped):
|
def __init__(self, fget):
|
||||||
# If a name is provided (as an argument) then this will be the string
|
# If a name is provided (as an argument) then this will be the string
|
||||||
# to place the cached attribute under if not then it will be the
|
# to place the cached attribute under if not then it will be the
|
||||||
# function itself to be wrapped into a property.
|
# function itself to be wrapped into a property.
|
||||||
if inspect.isfunction(wrapped):
|
if inspect.isfunction(fget):
|
||||||
self._wrapped = wrapped
|
self._fget = fget
|
||||||
self._wrapped_attr = "_%s" % (wrapped.__name__)
|
self._attr_name = "_%s" % (fget.__name__)
|
||||||
else:
|
else:
|
||||||
self._wrapped_attr = wrapped
|
self._attr_name = fget
|
||||||
self._wrapped = None
|
self._fget = None
|
||||||
|
|
||||||
def __call__(self, fget):
|
def __call__(self, fget):
|
||||||
# If __init__ received a string then this will be the function to be
|
# If __init__ received a string then this will be the function to be
|
||||||
# wrapped as a property (if __init__ got a function then this will not
|
# wrapped as a property (if __init__ got a function then this will not
|
||||||
# be called).
|
# be called).
|
||||||
self._wrapped = fget
|
self._fget = fget
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def __get__(self, source, owner):
|
def __set__(self, instance, value):
|
||||||
|
raise AttributeError("can't set attribute")
|
||||||
|
|
||||||
|
def __delete__(self, instance):
|
||||||
|
raise AttributeError("can't delete attribute")
|
||||||
|
|
||||||
|
def __get__(self, instance, owner):
|
||||||
try:
|
try:
|
||||||
return getattr(source, self._wrapped_attr)
|
return getattr(instance, self._attr_name)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
setattr(source, self._wrapped_attr, self._wrapped(source))
|
value = self._fget(instance)
|
||||||
return getattr(source, self._wrapped_attr)
|
setattr(instance, self._attr_name, value)
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
def wallclock():
|
def wallclock():
|
||||||
|
|||||||
Reference in New Issue
Block a user