183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Test case for property 283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# more tests are in test_descr 383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport sys 583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport unittest 683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom test.test_support import run_unittest 783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass PropertyBase(Exception): 983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh pass 1083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 1183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass PropertyGet(PropertyBase): 1283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh pass 1383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 1483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass PropertySet(PropertyBase): 1583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh pass 1683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 1783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass PropertyDel(PropertyBase): 1883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh pass 1983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 2083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass BaseClass(object): 2183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def __init__(self): 2283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._spam = 5 2383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 2483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh @property 2583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def spam(self): 2683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """BaseClass.getter""" 2783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return self._spam 2883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 2983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh @spam.setter 3083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def spam(self, value): 3183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._spam = value 3283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 3383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh @spam.deleter 3483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def spam(self): 3583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh del self._spam 3683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 3783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass SubClass(BaseClass): 3883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 3983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh @BaseClass.spam.getter 4083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def spam(self): 4183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """SubClass.getter""" 4283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh raise PropertyGet(self._spam) 4383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 4483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh @spam.setter 4583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def spam(self, value): 4683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh raise PropertySet(self._spam) 4783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 4883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh @spam.deleter 4983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def spam(self): 5083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh raise PropertyDel(self._spam) 5183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 5283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass PropertyDocBase(object): 5383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh _spam = 1 5483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def _get_spam(self): 5583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return self._spam 5683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh spam = property(_get_spam, doc="spam spam spam") 5783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 5883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass PropertyDocSub(PropertyDocBase): 5983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh @PropertyDocBase.spam.getter 6083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def spam(self): 6183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """The decorator does not use this doc string""" 6283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return self._spam 6383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 6483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass PropertySubNewGetter(BaseClass): 6583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh @BaseClass.spam.getter 6683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def spam(self): 6783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """new docstring""" 6883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return 5 6983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 7083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass PropertyNewGetter(object): 7183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh @property 7283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def spam(self): 7383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """original docstring""" 7483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return 1 7583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh @spam.getter 7683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def spam(self): 7783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """new docstring""" 7883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return 8 7983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 8083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass PropertyTests(unittest.TestCase): 8183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def test_property_decorator_baseclass(self): 8283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # see #1620 8383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh base = BaseClass() 8483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(base.spam, 5) 8583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(base._spam, 5) 8683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh base.spam = 10 8783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(base.spam, 10) 8883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(base._spam, 10) 8983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh delattr(base, "spam") 9083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertTrue(not hasattr(base, "spam")) 9183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertTrue(not hasattr(base, "_spam")) 9283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh base.spam = 20 9383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(base.spam, 20) 9483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(base._spam, 20) 9583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 9683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def test_property_decorator_subclass(self): 9783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # see #1620 9883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh sub = SubClass() 9983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertRaises(PropertyGet, getattr, sub, "spam") 10083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertRaises(PropertySet, setattr, sub, "spam", None) 10183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertRaises(PropertyDel, delattr, sub, "spam") 10283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 10383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh @unittest.skipIf(sys.flags.optimize >= 2, 10483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "Docstrings are omitted with -O2 and above") 10583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def test_property_decorator_subclass_doc(self): 10683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh sub = SubClass() 10783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(sub.__class__.spam.__doc__, "SubClass.getter") 10883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 10983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh @unittest.skipIf(sys.flags.optimize >= 2, 11083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "Docstrings are omitted with -O2 and above") 11183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def test_property_decorator_baseclass_doc(self): 11283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh base = BaseClass() 11383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(base.__class__.spam.__doc__, "BaseClass.getter") 11483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 11583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def test_property_decorator_doc(self): 11683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh base = PropertyDocBase() 11783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh sub = PropertyDocSub() 11883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(base.__class__.spam.__doc__, "spam spam spam") 11983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(sub.__class__.spam.__doc__, "spam spam spam") 12083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 12183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh @unittest.skipIf(sys.flags.optimize >= 2, 12283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "Docstrings are omitted with -O2 and above") 12383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def test_property_getter_doc_override(self): 12483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh newgettersub = PropertySubNewGetter() 12583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(newgettersub.spam, 5) 12683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(newgettersub.__class__.spam.__doc__, "new docstring") 12783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh newgetter = PropertyNewGetter() 12883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(newgetter.spam, 8) 12983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(newgetter.__class__.spam.__doc__, "new docstring") 13083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 13183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 13283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Issue 5890: subclasses of property do not preserve method __doc__ strings 13383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass PropertySub(property): 13483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """This is a subclass of property""" 13583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 13683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass PropertySubSlots(property): 13783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """This is a subclass of property that defines __slots__""" 13883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh __slots__ = () 13983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 14083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass PropertySubclassTests(unittest.TestCase): 14183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 14283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def test_slots_docstring_copy_exception(self): 14383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh try: 14483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh class Foo(object): 14583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh @PropertySubSlots 14683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def spam(self): 14783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """Trying to copy this docstring will raise an exception""" 14883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return 1 14983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh except AttributeError: 15083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh pass 15183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh else: 15283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh raise Exception("AttributeError not raised") 15383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 15483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh @unittest.skipIf(sys.flags.optimize >= 2, 15583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "Docstrings are omitted with -O2 and above") 15683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def test_docstring_copy(self): 15783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh class Foo(object): 15883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh @PropertySub 15983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def spam(self): 16083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """spam wrapped in property subclass""" 16183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return 1 16283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual( 16383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh Foo.spam.__doc__, 16483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "spam wrapped in property subclass") 16583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 16683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh @unittest.skipIf(sys.flags.optimize >= 2, 16783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "Docstrings are omitted with -O2 and above") 16883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def test_property_setter_copies_getter_docstring(self): 16983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh class Foo(object): 17083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def __init__(self): self._spam = 1 17183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh @PropertySub 17283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def spam(self): 17383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """spam wrapped in property subclass""" 17483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return self._spam 17583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh @spam.setter 17683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def spam(self, value): 17783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """this docstring is ignored""" 17883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._spam = value 17983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh foo = Foo() 18083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(foo.spam, 1) 18183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh foo.spam = 2 18283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(foo.spam, 2) 18383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual( 18483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh Foo.spam.__doc__, 18583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "spam wrapped in property subclass") 18683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh class FooSub(Foo): 18783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh @Foo.spam.setter 18883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def spam(self, value): 18983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """another ignored docstring""" 19083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._spam = 'eggs' 19183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh foosub = FooSub() 19283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(foosub.spam, 1) 19383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh foosub.spam = 7 19483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(foosub.spam, 'eggs') 19583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual( 19683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh FooSub.spam.__doc__, 19783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "spam wrapped in property subclass") 19883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 19983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh @unittest.skipIf(sys.flags.optimize >= 2, 20083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "Docstrings are omitted with -O2 and above") 20183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def test_property_new_getter_new_docstring(self): 20283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 20383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh class Foo(object): 20483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh @PropertySub 20583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def spam(self): 20683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """a docstring""" 20783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return 1 20883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh @spam.getter 20983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def spam(self): 21083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """a new docstring""" 21183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return 2 21283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(Foo.spam.__doc__, "a new docstring") 21383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh class FooBase(object): 21483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh @PropertySub 21583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def spam(self): 21683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """a docstring""" 21783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return 1 21883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh class Foo2(FooBase): 21983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh @FooBase.spam.getter 22083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def spam(self): 22183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """a new docstring""" 22283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return 2 22383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(Foo.spam.__doc__, "a new docstring") 22483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 22583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 22683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 22783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef test_main(): 22883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh run_unittest(PropertyTests, PropertySubclassTests) 22983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 23083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehif __name__ == '__main__': 23183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh test_main() 232