blob: 7a8003f62dea327c2942a2d3dbd4481eea5567b0 [file] [log] [blame]
Christian Heimes90e10e72007-12-14 02:35:23 +00001# Test case for property
2# more tests are in test_descr
3
4import unittest
5from test.test_support import run_unittest
6
7class PropertyBase(Exception):
8 pass
9
10class PropertyGet(PropertyBase):
11 pass
12
13class PropertySet(PropertyBase):
14 pass
15
16class PropertyDel(PropertyBase):
17 pass
18
19class BaseClass(object):
20 def __init__(self):
21 self._spam = 5
22
23 @property
24 def spam(self):
25 """BaseClass.getter"""
26 return self._spam
27
28 @spam.setter
29 def spam(self, value):
30 self._spam = value
31
32 @spam.deleter
33 def spam(self):
34 del self._spam
35
36class SubClass(BaseClass):
37
38 @BaseClass.spam.getter
39 def spam(self):
40 """SubClass.getter"""
41 raise PropertyGet(self._spam)
42
43 @spam.setter
44 def spam(self, value):
45 raise PropertySet(self._spam)
46
47 @spam.deleter
48 def spam(self):
49 raise PropertyDel(self._spam)
50
51class PropertyDocBase(object):
52 _spam = 1
53 def _get_spam(self):
54 return self._spam
55 spam = property(_get_spam, doc="spam spam spam")
56
57class PropertyDocSub(PropertyDocBase):
58 @PropertyDocBase.spam.getter
59 def spam(self):
60 """The decorator does not use this doc string"""
61 return self._spam
62
R. David Murray7ba8e1c2009-05-04 22:16:24 +000063class PropertySubNewGetter(BaseClass):
64 @BaseClass.spam.getter
65 def spam(self):
66 """new docstring"""
67 return 5
68
69class PropertyNewGetter(object):
70 @property
71 def spam(self):
72 """original docstring"""
73 return 1
74 @spam.getter
75 def spam(self):
76 """new docstring"""
77 return 8
78
Christian Heimes90e10e72007-12-14 02:35:23 +000079class PropertyTests(unittest.TestCase):
80 def test_property_decorator_baseclass(self):
81 # see #1620
82 base = BaseClass()
83 self.assertEqual(base.spam, 5)
84 self.assertEqual(base._spam, 5)
85 base.spam = 10
86 self.assertEqual(base.spam, 10)
87 self.assertEqual(base._spam, 10)
88 delattr(base, "spam")
89 self.assert_(not hasattr(base, "spam"))
90 self.assert_(not hasattr(base, "_spam"))
91 base.spam = 20
92 self.assertEqual(base.spam, 20)
93 self.assertEqual(base._spam, 20)
94 self.assertEqual(base.__class__.spam.__doc__, "BaseClass.getter")
95
96 def test_property_decorator_subclass(self):
97 # see #1620
98 sub = SubClass()
99 self.assertRaises(PropertyGet, getattr, sub, "spam")
100 self.assertRaises(PropertySet, setattr, sub, "spam", None)
101 self.assertRaises(PropertyDel, delattr, sub, "spam")
102 self.assertEqual(sub.__class__.spam.__doc__, "SubClass.getter")
103
104 def test_property_decorator_doc(self):
105 base = PropertyDocBase()
106 sub = PropertyDocSub()
107 self.assertEqual(base.__class__.spam.__doc__, "spam spam spam")
108 self.assertEqual(sub.__class__.spam.__doc__, "spam spam spam")
109
R. David Murray7ba8e1c2009-05-04 22:16:24 +0000110 def test_property_getter_doc_override(self):
111 newgettersub = PropertySubNewGetter()
112 self.assertEqual(newgettersub.spam, 5)
113 self.assertEqual(newgettersub.__class__.spam.__doc__, "new docstring")
114 newgetter = PropertyNewGetter()
115 self.assertEqual(newgetter.spam, 8)
116 self.assertEqual(newgetter.__class__.spam.__doc__, "new docstring")
117
118
119# Issue 5890: subclasses of property do not preserve method __doc__ strings
120class PropertySub(property):
121 """This is a subclass of property"""
122
123class PropertySubSlots(property):
124 """This is a subclass of property that defines __slots__"""
125 __slots__ = ()
126
127class PropertySubclassTests(unittest.TestCase):
128
129 def test_docstring_copy(self):
130 class Foo(object):
131 @PropertySub
132 def spam(self):
133 """spam wrapped in property subclass"""
134 return 1
135 self.assertEqual(
136 Foo.spam.__doc__,
137 "spam wrapped in property subclass")
138
139 def test_slots_docstring_copy_exception(self):
140 try:
141 class Foo(object):
142 @PropertySubSlots
143 def spam(self):
144 """Trying to copy this docstring will raise an exception"""
145 return 1
146 except AttributeError:
147 pass
148 else:
149 raise Exception("AttributeError not raised")
150
151 def test_property_setter_copies_getter_docstring(self):
152 class Foo(object):
153 def __init__(self): self._spam = 1
154 @PropertySub
155 def spam(self):
156 """spam wrapped in property subclass"""
157 return self._spam
158 @spam.setter
159 def spam(self, value):
160 """this docstring is ignored"""
161 self._spam = value
162 foo = Foo()
163 self.assertEqual(foo.spam, 1)
164 foo.spam = 2
165 self.assertEqual(foo.spam, 2)
166 self.assertEqual(
167 Foo.spam.__doc__,
168 "spam wrapped in property subclass")
169 class FooSub(Foo):
170 @Foo.spam.setter
171 def spam(self, value):
172 """another ignored docstring"""
173 self._spam = 'eggs'
174 foosub = FooSub()
175 self.assertEqual(foosub.spam, 1)
176 foosub.spam = 7
177 self.assertEqual(foosub.spam, 'eggs')
178 self.assertEqual(
179 FooSub.spam.__doc__,
180 "spam wrapped in property subclass")
181
182 def test_property_new_getter_new_docstring(self):
183
184 class Foo(object):
185 @PropertySub
186 def spam(self):
187 """a docstring"""
188 return 1
189 @spam.getter
190 def spam(self):
191 """a new docstring"""
192 return 2
193 self.assertEqual(Foo.spam.__doc__, "a new docstring")
194 class FooBase(object):
195 @PropertySub
196 def spam(self):
197 """a docstring"""
198 return 1
199 class Foo2(FooBase):
200 @FooBase.spam.getter
201 def spam(self):
202 """a new docstring"""
203 return 2
204 self.assertEqual(Foo.spam.__doc__, "a new docstring")
205
206
207
Christian Heimes90e10e72007-12-14 02:35:23 +0000208def test_main():
R. David Murray7ba8e1c2009-05-04 22:16:24 +0000209 run_unittest(PropertyTests, PropertySubclassTests)
Christian Heimes90e10e72007-12-14 02:35:23 +0000210
211if __name__ == '__main__':
212 test_main()