Add better error reporting for MemoryErrors caused by str->float conversions.
[python.git] / Lib / test / test_property.py
blob684f8fe5fb2cdbb7a2d3948d0bc49b0e7ec8c8d9
1 # Test case for property
2 # more tests are in test_descr
4 import unittest
5 from test.test_support import run_unittest
7 class PropertyBase(Exception):
8 pass
10 class PropertyGet(PropertyBase):
11 pass
13 class PropertySet(PropertyBase):
14 pass
16 class PropertyDel(PropertyBase):
17 pass
19 class BaseClass(object):
20 def __init__(self):
21 self._spam = 5
23 @property
24 def spam(self):
25 """BaseClass.getter"""
26 return self._spam
28 @spam.setter
29 def spam(self, value):
30 self._spam = value
32 @spam.deleter
33 def spam(self):
34 del self._spam
36 class SubClass(BaseClass):
38 @BaseClass.spam.getter
39 def spam(self):
40 """SubClass.getter"""
41 raise PropertyGet(self._spam)
43 @spam.setter
44 def spam(self, value):
45 raise PropertySet(self._spam)
47 @spam.deleter
48 def spam(self):
49 raise PropertyDel(self._spam)
51 class PropertyDocBase(object):
52 _spam = 1
53 def _get_spam(self):
54 return self._spam
55 spam = property(_get_spam, doc="spam spam spam")
57 class PropertyDocSub(PropertyDocBase):
58 @PropertyDocBase.spam.getter
59 def spam(self):
60 """The decorator does not use this doc string"""
61 return self._spam
63 class PropertySubNewGetter(BaseClass):
64 @BaseClass.spam.getter
65 def spam(self):
66 """new docstring"""
67 return 5
69 class 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
79 class 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.assertTrue(not hasattr(base, "spam"))
90 self.assertTrue(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")
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")
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")
110 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")
119 # Issue 5890: subclasses of property do not preserve method __doc__ strings
120 class PropertySub(property):
121 """This is a subclass of property"""
123 class PropertySubSlots(property):
124 """This is a subclass of property that defines __slots__"""
125 __slots__ = ()
127 class PropertySubclassTests(unittest.TestCase):
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")
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")
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")
182 def test_property_new_getter_new_docstring(self):
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")
208 def test_main():
209 run_unittest(PropertyTests, PropertySubclassTests)
211 if __name__ == '__main__':
212 test_main()