From 31b84e1c51c7660d0fed5a3ee98c67c62207a01c Mon Sep 17 00:00:00 2001 From: Joshua Harlow Date: Mon, 2 Jun 2014 11:14:50 -0700 Subject: [PATCH] Ensure cachedproperty descriptor picks up docstrings Closes-Bug: #1325677 Change-Id: I6366dea5458adec30e945a9834e15da946813461 --- taskflow/tests/unit/test_utils.py | 20 ++++++++++++++++++++ taskflow/utils/misc.py | 5 +++++ 2 files changed, 25 insertions(+) diff --git a/taskflow/tests/unit/test_utils.py b/taskflow/tests/unit/test_utils.py index ffabe7df..1d1ea336 100644 --- a/taskflow/tests/unit/test_utils.py +++ b/taskflow/tests/unit/test_utils.py @@ -16,6 +16,7 @@ import collections import functools +import inspect import sys import time @@ -370,6 +371,25 @@ class CachedPropertyTest(test.TestCase): self.assertRaises(AttributeError, try_set, a) self.assertEqual('b', a.b) + def test_documented_property(self): + + class A(object): + @misc.cachedproperty + def b(self): + """I like bees.""" + return 'b' + + self.assertEqual("I like bees.", inspect.getdoc(A.b)) + + def test_undocumented_property(self): + + class A(object): + @misc.cachedproperty + def b(self): + return 'b' + + self.assertEqual(None, inspect.getdoc(A.b)) + class AttrDictTest(test.TestCase): def test_ok_create(self): diff --git a/taskflow/utils/misc.py b/taskflow/utils/misc.py index 623fce32..d2360c9b 100644 --- a/taskflow/utils/misc.py +++ b/taskflow/utils/misc.py @@ -187,15 +187,18 @@ class cachedproperty(object): if inspect.isfunction(fget): self._fget = fget self._attr_name = "_%s" % (fget.__name__) + self.__doc__ = getattr(fget, '__doc__', None) else: self._attr_name = fget self._fget = None + self.__doc__ = None def __call__(self, fget): # 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 # be called). self._fget = fget + self.__doc__ = getattr(fget, '__doc__', None) return self def __set__(self, instance, value): @@ -205,6 +208,8 @@ class cachedproperty(object): raise AttributeError("can't delete attribute") def __get__(self, instance, owner): + if instance is None: + return self try: return getattr(instance, self._attr_name) except AttributeError: