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