blob: cef7d476e13aeea9c8a0d27e4428471c6f7c418f [file] [log] [blame]
Benjamin Peterson4585ca92009-04-18 20:50:24 +00001import __builtin__
Armin Rigo9790a272007-05-02 19:23:31 +00002import types
Georg Brandl48545522008-02-02 10:12:36 +00003import unittest
4import warnings
Tim Peters4d9b4662002-04-16 01:59:17 +00005
Georg Brandl48545522008-02-02 10:12:36 +00006from copy import deepcopy
7from test import test_support
Tim Peters6d6c1a32001-08-02 04:15:00 +00008
Guido van Rossum875eeaa2001-10-11 18:33:53 +00009
Georg Brandl48545522008-02-02 10:12:36 +000010class OperatorsTest(unittest.TestCase):
Tim Peters6d6c1a32001-08-02 04:15:00 +000011
Georg Brandl48545522008-02-02 10:12:36 +000012 def __init__(self, *args, **kwargs):
13 unittest.TestCase.__init__(self, *args, **kwargs)
14 self.binops = {
15 'add': '+',
16 'sub': '-',
17 'mul': '*',
18 'div': '/',
19 'divmod': 'divmod',
20 'pow': '**',
21 'lshift': '<<',
22 'rshift': '>>',
23 'and': '&',
24 'xor': '^',
25 'or': '|',
26 'cmp': 'cmp',
27 'lt': '<',
28 'le': '<=',
29 'eq': '==',
30 'ne': '!=',
31 'gt': '>',
32 'ge': '>=',
33 }
Tim Peters3caca232001-12-06 06:23:26 +000034
Georg Brandl48545522008-02-02 10:12:36 +000035 for name, expr in self.binops.items():
36 if expr.islower():
37 expr = expr + "(a, b)"
38 else:
39 expr = 'a %s b' % expr
40 self.binops[name] = expr
Tim Peters3caca232001-12-06 06:23:26 +000041
Georg Brandl48545522008-02-02 10:12:36 +000042 self.unops = {
43 'pos': '+',
44 'neg': '-',
45 'abs': 'abs',
46 'invert': '~',
47 'int': 'int',
48 'long': 'long',
49 'float': 'float',
50 'oct': 'oct',
51 'hex': 'hex',
52 }
Tim Peters6d6c1a32001-08-02 04:15:00 +000053
Georg Brandl48545522008-02-02 10:12:36 +000054 for name, expr in self.unops.items():
55 if expr.islower():
56 expr = expr + "(a)"
57 else:
58 expr = '%s a' % expr
59 self.unops[name] = expr
Tim Peters6d6c1a32001-08-02 04:15:00 +000060
Georg Brandl48545522008-02-02 10:12:36 +000061 def setUp(self):
62 self.original_filters = warnings.filters[:]
63 warnings.filterwarnings("ignore",
64 r'complex divmod\(\), // and % are deprecated$',
65 DeprecationWarning, r'(<string>|%s)$' % __name__)
Tim Peters6d6c1a32001-08-02 04:15:00 +000066
Georg Brandl48545522008-02-02 10:12:36 +000067 def tearDown(self):
68 warnings.filters = self.original_filters
Tim Peters6d6c1a32001-08-02 04:15:00 +000069
Georg Brandl48545522008-02-02 10:12:36 +000070 def unop_test(self, a, res, expr="len(a)", meth="__len__"):
71 d = {'a': a}
72 self.assertEqual(eval(expr, d), res)
73 t = type(a)
74 m = getattr(t, meth)
Tim Peters6d6c1a32001-08-02 04:15:00 +000075
Georg Brandl48545522008-02-02 10:12:36 +000076 # Find method in parent class
77 while meth not in t.__dict__:
78 t = t.__bases__[0]
Tim Peters2f93e282001-10-04 05:27:00 +000079
Georg Brandl48545522008-02-02 10:12:36 +000080 self.assertEqual(m, t.__dict__[meth])
81 self.assertEqual(m(a), res)
82 bm = getattr(a, meth)
83 self.assertEqual(bm(), res)
Tim Peters2f93e282001-10-04 05:27:00 +000084
Georg Brandl48545522008-02-02 10:12:36 +000085 def binop_test(self, a, b, res, expr="a+b", meth="__add__"):
86 d = {'a': a, 'b': b}
Tim Peters2f93e282001-10-04 05:27:00 +000087
Georg Brandl48545522008-02-02 10:12:36 +000088 # XXX Hack so this passes before 2.3 when -Qnew is specified.
89 if meth == "__div__" and 1/2 == 0.5:
90 meth = "__truediv__"
Tim Peters2f93e282001-10-04 05:27:00 +000091
Georg Brandl48545522008-02-02 10:12:36 +000092 if meth == '__divmod__': pass
Tim Peters2f93e282001-10-04 05:27:00 +000093
Georg Brandl48545522008-02-02 10:12:36 +000094 self.assertEqual(eval(expr, d), res)
95 t = type(a)
96 m = getattr(t, meth)
97 while meth not in t.__dict__:
98 t = t.__bases__[0]
99 self.assertEqual(m, t.__dict__[meth])
100 self.assertEqual(m(a, b), res)
101 bm = getattr(a, meth)
102 self.assertEqual(bm(b), res)
Tim Peters2f93e282001-10-04 05:27:00 +0000103
Georg Brandl48545522008-02-02 10:12:36 +0000104 def ternop_test(self, a, b, c, res, expr="a[b:c]", meth="__getslice__"):
105 d = {'a': a, 'b': b, 'c': c}
106 self.assertEqual(eval(expr, d), res)
107 t = type(a)
108 m = getattr(t, meth)
109 while meth not in t.__dict__:
110 t = t.__bases__[0]
111 self.assertEqual(m, t.__dict__[meth])
112 self.assertEqual(m(a, b, c), res)
113 bm = getattr(a, meth)
114 self.assertEqual(bm(b, c), res)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000115
Georg Brandl48545522008-02-02 10:12:36 +0000116 def setop_test(self, a, b, res, stmt="a+=b", meth="__iadd__"):
117 d = {'a': deepcopy(a), 'b': b}
118 exec stmt in d
119 self.assertEqual(d['a'], res)
120 t = type(a)
121 m = getattr(t, meth)
122 while meth not in t.__dict__:
123 t = t.__bases__[0]
124 self.assertEqual(m, t.__dict__[meth])
125 d['a'] = deepcopy(a)
126 m(d['a'], b)
127 self.assertEqual(d['a'], res)
128 d['a'] = deepcopy(a)
129 bm = getattr(d['a'], meth)
130 bm(b)
131 self.assertEqual(d['a'], res)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000132
Georg Brandl48545522008-02-02 10:12:36 +0000133 def set2op_test(self, a, b, c, res, stmt="a[b]=c", meth="__setitem__"):
134 d = {'a': deepcopy(a), 'b': b, 'c': c}
135 exec stmt in d
136 self.assertEqual(d['a'], res)
137 t = type(a)
138 m = getattr(t, meth)
139 while meth not in t.__dict__:
140 t = t.__bases__[0]
141 self.assertEqual(m, t.__dict__[meth])
142 d['a'] = deepcopy(a)
143 m(d['a'], b, c)
144 self.assertEqual(d['a'], res)
145 d['a'] = deepcopy(a)
146 bm = getattr(d['a'], meth)
147 bm(b, c)
148 self.assertEqual(d['a'], res)
149
150 def set3op_test(self, a, b, c, d, res, stmt="a[b:c]=d", meth="__setslice__"):
151 dictionary = {'a': deepcopy(a), 'b': b, 'c': c, 'd': d}
152 exec stmt in dictionary
153 self.assertEqual(dictionary['a'], res)
154 t = type(a)
155 while meth not in t.__dict__:
156 t = t.__bases__[0]
157 m = getattr(t, meth)
158 self.assertEqual(m, t.__dict__[meth])
159 dictionary['a'] = deepcopy(a)
160 m(dictionary['a'], b, c, d)
161 self.assertEqual(dictionary['a'], res)
162 dictionary['a'] = deepcopy(a)
163 bm = getattr(dictionary['a'], meth)
164 bm(b, c, d)
165 self.assertEqual(dictionary['a'], res)
166
167 def test_lists(self):
168 # Testing list operations...
169 # Asserts are within individual test methods
170 self.binop_test([1], [2], [1,2], "a+b", "__add__")
171 self.binop_test([1,2,3], 2, 1, "b in a", "__contains__")
172 self.binop_test([1,2,3], 4, 0, "b in a", "__contains__")
173 self.binop_test([1,2,3], 1, 2, "a[b]", "__getitem__")
174 self.ternop_test([1,2,3], 0, 2, [1,2], "a[b:c]", "__getslice__")
175 self.setop_test([1], [2], [1,2], "a+=b", "__iadd__")
176 self.setop_test([1,2], 3, [1,2,1,2,1,2], "a*=b", "__imul__")
177 self.unop_test([1,2,3], 3, "len(a)", "__len__")
178 self.binop_test([1,2], 3, [1,2,1,2,1,2], "a*b", "__mul__")
179 self.binop_test([1,2], 3, [1,2,1,2,1,2], "b*a", "__rmul__")
180 self.set2op_test([1,2], 1, 3, [1,3], "a[b]=c", "__setitem__")
181 self.set3op_test([1,2,3,4], 1, 3, [5,6], [1,5,6,4], "a[b:c]=d",
182 "__setslice__")
183
184 def test_dicts(self):
185 # Testing dict operations...
186 self.binop_test({1:2}, {2:1}, -1, "cmp(a,b)", "__cmp__")
187 self.binop_test({1:2,3:4}, 1, 1, "b in a", "__contains__")
188 self.binop_test({1:2,3:4}, 2, 0, "b in a", "__contains__")
189 self.binop_test({1:2,3:4}, 1, 2, "a[b]", "__getitem__")
190
191 d = {1:2, 3:4}
192 l1 = []
193 for i in d.keys():
194 l1.append(i)
195 l = []
196 for i in iter(d):
197 l.append(i)
198 self.assertEqual(l, l1)
199 l = []
200 for i in d.__iter__():
201 l.append(i)
202 self.assertEqual(l, l1)
203 l = []
204 for i in dict.__iter__(d):
205 l.append(i)
206 self.assertEqual(l, l1)
207 d = {1:2, 3:4}
208 self.unop_test(d, 2, "len(a)", "__len__")
209 self.assertEqual(eval(repr(d), {}), d)
210 self.assertEqual(eval(d.__repr__(), {}), d)
211 self.set2op_test({1:2,3:4}, 2, 3, {1:2,2:3,3:4}, "a[b]=c",
212 "__setitem__")
213
214 # Tests for unary and binary operators
215 def number_operators(self, a, b, skip=[]):
216 dict = {'a': a, 'b': b}
217
218 for name, expr in self.binops.items():
219 if name not in skip:
220 name = "__%s__" % name
221 if hasattr(a, name):
222 res = eval(expr, dict)
223 self.binop_test(a, b, res, expr, name)
224
225 for name, expr in self.unops.items():
226 if name not in skip:
227 name = "__%s__" % name
228 if hasattr(a, name):
229 res = eval(expr, dict)
230 self.unop_test(a, res, expr, name)
231
232 def test_ints(self):
233 # Testing int operations...
234 self.number_operators(100, 3)
235 # The following crashes in Python 2.2
236 self.assertEqual((1).__nonzero__(), 1)
237 self.assertEqual((0).__nonzero__(), 0)
238 # This returns 'NotImplemented' in Python 2.2
239 class C(int):
240 def __add__(self, other):
241 return NotImplemented
242 self.assertEqual(C(5L), 5)
Tim Peters25786c02001-09-02 08:22:48 +0000243 try:
Georg Brandl48545522008-02-02 10:12:36 +0000244 C() + ""
Tim Peters25786c02001-09-02 08:22:48 +0000245 except TypeError:
246 pass
247 else:
Georg Brandl48545522008-02-02 10:12:36 +0000248 self.fail("NotImplemented should have caused TypeError")
249 import sys
Tim Peters1fc240e2001-10-26 05:06:50 +0000250 try:
Georg Brandl48545522008-02-02 10:12:36 +0000251 C(sys.maxint+1)
252 except OverflowError:
Tim Peters1fc240e2001-10-26 05:06:50 +0000253 pass
254 else:
Georg Brandl48545522008-02-02 10:12:36 +0000255 self.fail("should have raised OverflowError")
Tim Peters1fc240e2001-10-26 05:06:50 +0000256
Georg Brandl48545522008-02-02 10:12:36 +0000257 def test_longs(self):
258 # Testing long operations...
259 self.number_operators(100L, 3L)
Tim Peters5d2b77c2001-09-03 05:47:38 +0000260
Georg Brandl48545522008-02-02 10:12:36 +0000261 def test_floats(self):
262 # Testing float operations...
263 self.number_operators(100.0, 3.0)
Tim Peters5d2b77c2001-09-03 05:47:38 +0000264
Georg Brandl48545522008-02-02 10:12:36 +0000265 def test_complexes(self):
266 # Testing complex operations...
267 self.number_operators(100.0j, 3.0j, skip=['lt', 'le', 'gt', 'ge',
268 'int', 'long', 'float'])
Tim Peters5d2b77c2001-09-03 05:47:38 +0000269
Georg Brandl48545522008-02-02 10:12:36 +0000270 class Number(complex):
271 __slots__ = ['prec']
272 def __new__(cls, *args, **kwds):
273 result = complex.__new__(cls, *args)
274 result.prec = kwds.get('prec', 12)
275 return result
276 def __repr__(self):
277 prec = self.prec
278 if self.imag == 0.0:
279 return "%.*g" % (prec, self.real)
280 if self.real == 0.0:
281 return "%.*gj" % (prec, self.imag)
282 return "(%.*g+%.*gj)" % (prec, self.real, prec, self.imag)
283 __str__ = __repr__
Tim Peters5d2b77c2001-09-03 05:47:38 +0000284
Georg Brandl48545522008-02-02 10:12:36 +0000285 a = Number(3.14, prec=6)
286 self.assertEqual(repr(a), "3.14")
287 self.assertEqual(a.prec, 6)
Tim Peters5d2b77c2001-09-03 05:47:38 +0000288
Georg Brandl48545522008-02-02 10:12:36 +0000289 a = Number(a, prec=2)
290 self.assertEqual(repr(a), "3.1")
291 self.assertEqual(a.prec, 2)
Tim Peters5d2b77c2001-09-03 05:47:38 +0000292
Georg Brandl48545522008-02-02 10:12:36 +0000293 a = Number(234.5)
294 self.assertEqual(repr(a), "234.5")
295 self.assertEqual(a.prec, 12)
Tim Peters5d2b77c2001-09-03 05:47:38 +0000296
Georg Brandl48545522008-02-02 10:12:36 +0000297 def test_spam_lists(self):
298 # Testing spamlist operations...
299 import copy, xxsubtype as spam
Tim Peters37a309d2001-09-04 01:20:04 +0000300
Georg Brandl48545522008-02-02 10:12:36 +0000301 def spamlist(l, memo=None):
302 import xxsubtype as spam
303 return spam.spamlist(l)
Tim Peters37a309d2001-09-04 01:20:04 +0000304
Georg Brandl48545522008-02-02 10:12:36 +0000305 # This is an ugly hack:
306 copy._deepcopy_dispatch[spam.spamlist] = spamlist
Tim Peters37a309d2001-09-04 01:20:04 +0000307
Georg Brandl48545522008-02-02 10:12:36 +0000308 self.binop_test(spamlist([1]), spamlist([2]), spamlist([1,2]), "a+b",
309 "__add__")
310 self.binop_test(spamlist([1,2,3]), 2, 1, "b in a", "__contains__")
311 self.binop_test(spamlist([1,2,3]), 4, 0, "b in a", "__contains__")
312 self.binop_test(spamlist([1,2,3]), 1, 2, "a[b]", "__getitem__")
313 self.ternop_test(spamlist([1,2,3]), 0, 2, spamlist([1,2]), "a[b:c]",
314 "__getslice__")
315 self.setop_test(spamlist([1]), spamlist([2]), spamlist([1,2]), "a+=b",
316 "__iadd__")
317 self.setop_test(spamlist([1,2]), 3, spamlist([1,2,1,2,1,2]), "a*=b",
318 "__imul__")
319 self.unop_test(spamlist([1,2,3]), 3, "len(a)", "__len__")
320 self.binop_test(spamlist([1,2]), 3, spamlist([1,2,1,2,1,2]), "a*b",
321 "__mul__")
322 self.binop_test(spamlist([1,2]), 3, spamlist([1,2,1,2,1,2]), "b*a",
323 "__rmul__")
324 self.set2op_test(spamlist([1,2]), 1, 3, spamlist([1,3]), "a[b]=c",
325 "__setitem__")
326 self.set3op_test(spamlist([1,2,3,4]), 1, 3, spamlist([5,6]),
327 spamlist([1,5,6,4]), "a[b:c]=d", "__setslice__")
328 # Test subclassing
329 class C(spam.spamlist):
330 def foo(self): return 1
331 a = C()
332 self.assertEqual(a, [])
333 self.assertEqual(a.foo(), 1)
334 a.append(100)
335 self.assertEqual(a, [100])
336 self.assertEqual(a.getstate(), 0)
337 a.setstate(42)
338 self.assertEqual(a.getstate(), 42)
Tim Peters37a309d2001-09-04 01:20:04 +0000339
Georg Brandl48545522008-02-02 10:12:36 +0000340 def test_spam_dicts(self):
341 # Testing spamdict operations...
342 import copy, xxsubtype as spam
343 def spamdict(d, memo=None):
344 import xxsubtype as spam
345 sd = spam.spamdict()
346 for k, v in d.items():
347 sd[k] = v
348 return sd
349 # This is an ugly hack:
350 copy._deepcopy_dispatch[spam.spamdict] = spamdict
Tim Peters37a309d2001-09-04 01:20:04 +0000351
Georg Brandl48545522008-02-02 10:12:36 +0000352 self.binop_test(spamdict({1:2}), spamdict({2:1}), -1, "cmp(a,b)",
353 "__cmp__")
354 self.binop_test(spamdict({1:2,3:4}), 1, 1, "b in a", "__contains__")
355 self.binop_test(spamdict({1:2,3:4}), 2, 0, "b in a", "__contains__")
356 self.binop_test(spamdict({1:2,3:4}), 1, 2, "a[b]", "__getitem__")
357 d = spamdict({1:2,3:4})
358 l1 = []
359 for i in d.keys():
360 l1.append(i)
361 l = []
362 for i in iter(d):
363 l.append(i)
364 self.assertEqual(l, l1)
365 l = []
366 for i in d.__iter__():
367 l.append(i)
368 self.assertEqual(l, l1)
369 l = []
370 for i in type(spamdict({})).__iter__(d):
371 l.append(i)
372 self.assertEqual(l, l1)
373 straightd = {1:2, 3:4}
374 spamd = spamdict(straightd)
375 self.unop_test(spamd, 2, "len(a)", "__len__")
376 self.unop_test(spamd, repr(straightd), "repr(a)", "__repr__")
377 self.set2op_test(spamdict({1:2,3:4}), 2, 3, spamdict({1:2,2:3,3:4}),
378 "a[b]=c", "__setitem__")
379 # Test subclassing
380 class C(spam.spamdict):
381 def foo(self): return 1
382 a = C()
383 self.assertEqual(a.items(), [])
384 self.assertEqual(a.foo(), 1)
385 a['foo'] = 'bar'
386 self.assertEqual(a.items(), [('foo', 'bar')])
387 self.assertEqual(a.getstate(), 0)
388 a.setstate(100)
389 self.assertEqual(a.getstate(), 100)
Tim Peters37a309d2001-09-04 01:20:04 +0000390
Georg Brandl48545522008-02-02 10:12:36 +0000391class ClassPropertiesAndMethods(unittest.TestCase):
Tim Peters37a309d2001-09-04 01:20:04 +0000392
Georg Brandl48545522008-02-02 10:12:36 +0000393 def test_python_dicts(self):
394 # Testing Python subclass of dict...
395 self.assert_(issubclass(dict, dict))
396 self.assert_(isinstance({}, dict))
397 d = dict()
398 self.assertEqual(d, {})
399 self.assert_(d.__class__ is dict)
400 self.assert_(isinstance(d, dict))
401 class C(dict):
402 state = -1
403 def __init__(self_local, *a, **kw):
404 if a:
405 self.assertEqual(len(a), 1)
406 self_local.state = a[0]
407 if kw:
408 for k, v in kw.items():
409 self_local[v] = k
410 def __getitem__(self, key):
411 return self.get(key, 0)
412 def __setitem__(self_local, key, value):
413 self.assert_(isinstance(key, type(0)))
414 dict.__setitem__(self_local, key, value)
415 def setstate(self, state):
416 self.state = state
417 def getstate(self):
418 return self.state
419 self.assert_(issubclass(C, dict))
420 a1 = C(12)
421 self.assertEqual(a1.state, 12)
422 a2 = C(foo=1, bar=2)
423 self.assertEqual(a2[1] == 'foo' and a2[2], 'bar')
424 a = C()
425 self.assertEqual(a.state, -1)
426 self.assertEqual(a.getstate(), -1)
427 a.setstate(0)
428 self.assertEqual(a.state, 0)
429 self.assertEqual(a.getstate(), 0)
430 a.setstate(10)
431 self.assertEqual(a.state, 10)
432 self.assertEqual(a.getstate(), 10)
433 self.assertEqual(a[42], 0)
434 a[42] = 24
435 self.assertEqual(a[42], 24)
436 N = 50
437 for i in range(N):
438 a[i] = C()
439 for j in range(N):
440 a[i][j] = i*j
441 for i in range(N):
442 for j in range(N):
443 self.assertEqual(a[i][j], i*j)
Tim Peters5d2b77c2001-09-03 05:47:38 +0000444
Georg Brandl48545522008-02-02 10:12:36 +0000445 def test_python_lists(self):
446 # Testing Python subclass of list...
447 class C(list):
448 def __getitem__(self, i):
449 return list.__getitem__(self, i) + 100
450 def __getslice__(self, i, j):
451 return (i, j)
452 a = C()
453 a.extend([0,1,2])
454 self.assertEqual(a[0], 100)
455 self.assertEqual(a[1], 101)
456 self.assertEqual(a[2], 102)
457 self.assertEqual(a[100:200], (100,200))
Tim Peterscaaff8d2001-09-10 23:12:14 +0000458
Georg Brandl48545522008-02-02 10:12:36 +0000459 def test_metaclass(self):
460 # Testing __metaclass__...
461 class C:
Guido van Rossume54616c2001-12-14 04:19:56 +0000462 __metaclass__ = type
Georg Brandl48545522008-02-02 10:12:36 +0000463 def __init__(self):
464 self.__state = 0
465 def getstate(self):
466 return self.__state
467 def setstate(self, state):
468 self.__state = state
469 a = C()
470 self.assertEqual(a.getstate(), 0)
471 a.setstate(10)
472 self.assertEqual(a.getstate(), 10)
473 class D:
474 class __metaclass__(type):
475 def myself(cls): return cls
476 self.assertEqual(D.myself(), D)
477 d = D()
478 self.assertEqual(d.__class__, D)
479 class M1(type):
480 def __new__(cls, name, bases, dict):
481 dict['__spam__'] = 1
482 return type.__new__(cls, name, bases, dict)
483 class C:
484 __metaclass__ = M1
485 self.assertEqual(C.__spam__, 1)
486 c = C()
487 self.assertEqual(c.__spam__, 1)
Guido van Rossume54616c2001-12-14 04:19:56 +0000488
Georg Brandl48545522008-02-02 10:12:36 +0000489 class _instance(object):
490 pass
491 class M2(object):
492 @staticmethod
493 def __new__(cls, name, bases, dict):
494 self = object.__new__(cls)
495 self.name = name
496 self.bases = bases
497 self.dict = dict
498 return self
499 def __call__(self):
500 it = _instance()
501 # Early binding of methods
502 for key in self.dict:
503 if key.startswith("__"):
504 continue
505 setattr(it, key, self.dict[key].__get__(it, self))
506 return it
507 class C:
508 __metaclass__ = M2
509 def spam(self):
510 return 42
511 self.assertEqual(C.name, 'C')
512 self.assertEqual(C.bases, ())
513 self.assert_('spam' in C.dict)
514 c = C()
515 self.assertEqual(c.spam(), 42)
Guido van Rossum9a818922002-11-14 19:50:14 +0000516
Georg Brandl48545522008-02-02 10:12:36 +0000517 # More metaclass examples
Guido van Rossum9a818922002-11-14 19:50:14 +0000518
Georg Brandl48545522008-02-02 10:12:36 +0000519 class autosuper(type):
520 # Automatically add __super to the class
521 # This trick only works for dynamic classes
522 def __new__(metaclass, name, bases, dict):
523 cls = super(autosuper, metaclass).__new__(metaclass,
524 name, bases, dict)
525 # Name mangling for __super removes leading underscores
526 while name[:1] == "_":
527 name = name[1:]
528 if name:
529 name = "_%s__super" % name
530 else:
531 name = "__super"
532 setattr(cls, name, super(cls))
533 return cls
534 class A:
535 __metaclass__ = autosuper
536 def meth(self):
537 return "A"
538 class B(A):
539 def meth(self):
540 return "B" + self.__super.meth()
541 class C(A):
542 def meth(self):
543 return "C" + self.__super.meth()
544 class D(C, B):
545 def meth(self):
546 return "D" + self.__super.meth()
547 self.assertEqual(D().meth(), "DCBA")
548 class E(B, C):
549 def meth(self):
550 return "E" + self.__super.meth()
551 self.assertEqual(E().meth(), "EBCA")
Guido van Rossum9a818922002-11-14 19:50:14 +0000552
Georg Brandl48545522008-02-02 10:12:36 +0000553 class autoproperty(type):
554 # Automatically create property attributes when methods
555 # named _get_x and/or _set_x are found
556 def __new__(metaclass, name, bases, dict):
557 hits = {}
558 for key, val in dict.iteritems():
559 if key.startswith("_get_"):
560 key = key[5:]
561 get, set = hits.get(key, (None, None))
562 get = val
563 hits[key] = get, set
564 elif key.startswith("_set_"):
565 key = key[5:]
566 get, set = hits.get(key, (None, None))
567 set = val
568 hits[key] = get, set
569 for key, (get, set) in hits.iteritems():
570 dict[key] = property(get, set)
571 return super(autoproperty, metaclass).__new__(metaclass,
572 name, bases, dict)
573 class A:
574 __metaclass__ = autoproperty
575 def _get_x(self):
576 return -self.__x
577 def _set_x(self, x):
578 self.__x = -x
579 a = A()
580 self.assert_(not hasattr(a, "x"))
581 a.x = 12
582 self.assertEqual(a.x, 12)
583 self.assertEqual(a._A__x, -12)
Guido van Rossum9a818922002-11-14 19:50:14 +0000584
Georg Brandl48545522008-02-02 10:12:36 +0000585 class multimetaclass(autoproperty, autosuper):
586 # Merge of multiple cooperating metaclasses
587 pass
588 class A:
589 __metaclass__ = multimetaclass
590 def _get_x(self):
591 return "A"
592 class B(A):
593 def _get_x(self):
594 return "B" + self.__super._get_x()
595 class C(A):
596 def _get_x(self):
597 return "C" + self.__super._get_x()
598 class D(C, B):
599 def _get_x(self):
600 return "D" + self.__super._get_x()
601 self.assertEqual(D().x, "DCBA")
Guido van Rossum9a818922002-11-14 19:50:14 +0000602
Georg Brandl48545522008-02-02 10:12:36 +0000603 # Make sure type(x) doesn't call x.__class__.__init__
604 class T(type):
605 counter = 0
606 def __init__(self, *args):
607 T.counter += 1
608 class C:
609 __metaclass__ = T
610 self.assertEqual(T.counter, 1)
611 a = C()
612 self.assertEqual(type(a), C)
613 self.assertEqual(T.counter, 1)
Guido van Rossum9a818922002-11-14 19:50:14 +0000614
Georg Brandl48545522008-02-02 10:12:36 +0000615 class C(object): pass
616 c = C()
617 try: c()
618 except TypeError: pass
619 else: self.fail("calling object w/o call method should raise "
620 "TypeError")
Guido van Rossum9a818922002-11-14 19:50:14 +0000621
Georg Brandl48545522008-02-02 10:12:36 +0000622 # Testing code to find most derived baseclass
623 class A(type):
624 def __new__(*args, **kwargs):
625 return type.__new__(*args, **kwargs)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000626
Georg Brandl48545522008-02-02 10:12:36 +0000627 class B(object):
628 pass
629
630 class C(object):
631 __metaclass__ = A
632
633 # The most derived metaclass of D is A rather than type.
634 class D(B, C):
635 pass
636
637 def test_module_subclasses(self):
638 # Testing Python subclass of module...
639 log = []
640 import types, sys
641 MT = type(sys)
642 class MM(MT):
643 def __init__(self, name):
644 MT.__init__(self, name)
645 def __getattribute__(self, name):
646 log.append(("getattr", name))
647 return MT.__getattribute__(self, name)
648 def __setattr__(self, name, value):
649 log.append(("setattr", name, value))
650 MT.__setattr__(self, name, value)
651 def __delattr__(self, name):
652 log.append(("delattr", name))
653 MT.__delattr__(self, name)
654 a = MM("a")
655 a.foo = 12
656 x = a.foo
657 del a.foo
658 self.assertEqual(log, [("setattr", "foo", 12),
659 ("getattr", "foo"),
660 ("delattr", "foo")])
661
662 # http://python.org/sf/1174712
663 try:
664 class Module(types.ModuleType, str):
665 pass
666 except TypeError:
667 pass
668 else:
669 self.fail("inheriting from ModuleType and str at the same time "
670 "should fail")
671
672 def test_multiple_inheritence(self):
673 # Testing multiple inheritance...
674 class C(object):
675 def __init__(self):
676 self.__state = 0
677 def getstate(self):
678 return self.__state
679 def setstate(self, state):
680 self.__state = state
681 a = C()
682 self.assertEqual(a.getstate(), 0)
683 a.setstate(10)
684 self.assertEqual(a.getstate(), 10)
685 class D(dict, C):
686 def __init__(self):
687 type({}).__init__(self)
688 C.__init__(self)
689 d = D()
690 self.assertEqual(d.keys(), [])
691 d["hello"] = "world"
692 self.assertEqual(d.items(), [("hello", "world")])
693 self.assertEqual(d["hello"], "world")
694 self.assertEqual(d.getstate(), 0)
695 d.setstate(10)
696 self.assertEqual(d.getstate(), 10)
697 self.assertEqual(D.__mro__, (D, dict, C, object))
698
699 # SF bug #442833
700 class Node(object):
701 def __int__(self):
702 return int(self.foo())
703 def foo(self):
704 return "23"
705 class Frag(Node, list):
706 def foo(self):
707 return "42"
708 self.assertEqual(Node().__int__(), 23)
709 self.assertEqual(int(Node()), 23)
710 self.assertEqual(Frag().__int__(), 42)
711 self.assertEqual(int(Frag()), 42)
712
713 # MI mixing classic and new-style classes.
714
715 class A:
716 x = 1
717
718 class B(A):
719 pass
720
721 class C(A):
722 x = 2
723
724 class D(B, C):
725 pass
726 self.assertEqual(D.x, 1)
727
728 # Classic MRO is preserved for a classic base class.
729 class E(D, object):
730 pass
731 self.assertEqual(E.__mro__, (E, D, B, A, C, object))
732 self.assertEqual(E.x, 1)
733
734 # But with a mix of classic bases, their MROs are combined using
735 # new-style MRO.
736 class F(B, C, object):
737 pass
738 self.assertEqual(F.__mro__, (F, B, C, A, object))
739 self.assertEqual(F.x, 2)
740
741 # Try something else.
742 class C:
743 def cmethod(self):
744 return "C a"
745 def all_method(self):
746 return "C b"
747
748 class M1(C, object):
749 def m1method(self):
750 return "M1 a"
751 def all_method(self):
752 return "M1 b"
753
754 self.assertEqual(M1.__mro__, (M1, C, object))
755 m = M1()
756 self.assertEqual(m.cmethod(), "C a")
757 self.assertEqual(m.m1method(), "M1 a")
758 self.assertEqual(m.all_method(), "M1 b")
759
760 class D(C):
761 def dmethod(self):
762 return "D a"
763 def all_method(self):
764 return "D b"
765
766 class M2(D, object):
767 def m2method(self):
768 return "M2 a"
769 def all_method(self):
770 return "M2 b"
771
772 self.assertEqual(M2.__mro__, (M2, D, C, object))
773 m = M2()
774 self.assertEqual(m.cmethod(), "C a")
775 self.assertEqual(m.dmethod(), "D a")
776 self.assertEqual(m.m2method(), "M2 a")
777 self.assertEqual(m.all_method(), "M2 b")
778
779 class M3(M1, M2, object):
780 def m3method(self):
781 return "M3 a"
782 def all_method(self):
783 return "M3 b"
784 self.assertEqual(M3.__mro__, (M3, M1, M2, D, C, object))
785 m = M3()
786 self.assertEqual(m.cmethod(), "C a")
787 self.assertEqual(m.dmethod(), "D a")
788 self.assertEqual(m.m1method(), "M1 a")
789 self.assertEqual(m.m2method(), "M2 a")
790 self.assertEqual(m.m3method(), "M3 a")
791 self.assertEqual(m.all_method(), "M3 b")
792
793 class Classic:
794 pass
795 try:
796 class New(Classic):
797 __metaclass__ = type
798 except TypeError:
799 pass
800 else:
801 self.fail("new class with only classic bases - shouldn't be")
802
803 def test_diamond_inheritence(self):
804 # Testing multiple inheritance special cases...
805 class A(object):
806 def spam(self): return "A"
807 self.assertEqual(A().spam(), "A")
808 class B(A):
809 def boo(self): return "B"
810 def spam(self): return "B"
811 self.assertEqual(B().spam(), "B")
812 self.assertEqual(B().boo(), "B")
813 class C(A):
814 def boo(self): return "C"
815 self.assertEqual(C().spam(), "A")
816 self.assertEqual(C().boo(), "C")
817 class D(B, C): pass
818 self.assertEqual(D().spam(), "B")
819 self.assertEqual(D().boo(), "B")
820 self.assertEqual(D.__mro__, (D, B, C, A, object))
821 class E(C, B): pass
822 self.assertEqual(E().spam(), "B")
823 self.assertEqual(E().boo(), "C")
824 self.assertEqual(E.__mro__, (E, C, B, A, object))
825 # MRO order disagreement
826 try:
827 class F(D, E): pass
828 except TypeError:
829 pass
830 else:
831 self.fail("expected MRO order disagreement (F)")
832 try:
833 class G(E, D): pass
834 except TypeError:
835 pass
836 else:
837 self.fail("expected MRO order disagreement (G)")
838
839 # see thread python-dev/2002-October/029035.html
840 def test_ex5_from_c3_switch(self):
841 # Testing ex5 from C3 switch discussion...
842 class A(object): pass
843 class B(object): pass
844 class C(object): pass
845 class X(A): pass
846 class Y(A): pass
847 class Z(X,B,Y,C): pass
848 self.assertEqual(Z.__mro__, (Z, X, B, Y, A, C, object))
849
850 # see "A Monotonic Superclass Linearization for Dylan",
851 # by Kim Barrett et al. (OOPSLA 1996)
852 def test_monotonicity(self):
853 # Testing MRO monotonicity...
854 class Boat(object): pass
855 class DayBoat(Boat): pass
856 class WheelBoat(Boat): pass
857 class EngineLess(DayBoat): pass
858 class SmallMultihull(DayBoat): pass
859 class PedalWheelBoat(EngineLess,WheelBoat): pass
860 class SmallCatamaran(SmallMultihull): pass
861 class Pedalo(PedalWheelBoat,SmallCatamaran): pass
862
863 self.assertEqual(PedalWheelBoat.__mro__,
864 (PedalWheelBoat, EngineLess, DayBoat, WheelBoat, Boat, object))
865 self.assertEqual(SmallCatamaran.__mro__,
866 (SmallCatamaran, SmallMultihull, DayBoat, Boat, object))
867 self.assertEqual(Pedalo.__mro__,
868 (Pedalo, PedalWheelBoat, EngineLess, SmallCatamaran,
869 SmallMultihull, DayBoat, WheelBoat, Boat, object))
870
871 # see "A Monotonic Superclass Linearization for Dylan",
872 # by Kim Barrett et al. (OOPSLA 1996)
873 def test_consistency_with_epg(self):
874 # Testing consistentcy with EPG...
875 class Pane(object): pass
876 class ScrollingMixin(object): pass
877 class EditingMixin(object): pass
878 class ScrollablePane(Pane,ScrollingMixin): pass
879 class EditablePane(Pane,EditingMixin): pass
880 class EditableScrollablePane(ScrollablePane,EditablePane): pass
881
882 self.assertEqual(EditableScrollablePane.__mro__,
883 (EditableScrollablePane, ScrollablePane, EditablePane, Pane,
884 ScrollingMixin, EditingMixin, object))
885
886 def test_mro_disagreement(self):
887 # Testing error messages for MRO disagreement...
888 mro_err_msg = """Cannot create a consistent method resolution
Raymond Hettingerf394df42003-04-06 19:13:41 +0000889order (MRO) for bases """
Raymond Hettinger83245b52003-03-12 04:25:42 +0000890
Georg Brandl48545522008-02-02 10:12:36 +0000891 def raises(exc, expected, callable, *args):
892 try:
893 callable(*args)
894 except exc, msg:
895 if not str(msg).startswith(expected):
896 self.fail("Message %r, expected %r" % (str(msg), expected))
897 else:
898 self.fail("Expected %s" % exc)
899
900 class A(object): pass
901 class B(A): pass
902 class C(object): pass
903
904 # Test some very simple errors
905 raises(TypeError, "duplicate base class A",
906 type, "X", (A, A), {})
907 raises(TypeError, mro_err_msg,
908 type, "X", (A, B), {})
909 raises(TypeError, mro_err_msg,
910 type, "X", (A, C, B), {})
911 # Test a slightly more complex error
912 class GridLayout(object): pass
913 class HorizontalGrid(GridLayout): pass
914 class VerticalGrid(GridLayout): pass
915 class HVGrid(HorizontalGrid, VerticalGrid): pass
916 class VHGrid(VerticalGrid, HorizontalGrid): pass
917 raises(TypeError, mro_err_msg,
918 type, "ConfusedGrid", (HVGrid, VHGrid), {})
919
920 def test_object_class(self):
921 # Testing object class...
922 a = object()
923 self.assertEqual(a.__class__, object)
924 self.assertEqual(type(a), object)
925 b = object()
926 self.assertNotEqual(a, b)
927 self.assertFalse(hasattr(a, "foo"))
Guido van Rossumd32047f2002-11-25 21:38:52 +0000928 try:
Georg Brandl48545522008-02-02 10:12:36 +0000929 a.foo = 12
930 except (AttributeError, TypeError):
931 pass
Guido van Rossumd32047f2002-11-25 21:38:52 +0000932 else:
Georg Brandl48545522008-02-02 10:12:36 +0000933 self.fail("object() should not allow setting a foo attribute")
934 self.assertFalse(hasattr(object(), "__dict__"))
Guido van Rossumd32047f2002-11-25 21:38:52 +0000935
Georg Brandl48545522008-02-02 10:12:36 +0000936 class Cdict(object):
937 pass
938 x = Cdict()
939 self.assertEqual(x.__dict__, {})
940 x.foo = 1
941 self.assertEqual(x.foo, 1)
942 self.assertEqual(x.__dict__, {'foo': 1})
Guido van Rossum37202612001-08-09 19:45:21 +0000943
Georg Brandl48545522008-02-02 10:12:36 +0000944 def test_slots(self):
945 # Testing __slots__...
946 class C0(object):
947 __slots__ = []
948 x = C0()
949 self.assertFalse(hasattr(x, "__dict__"))
950 self.assertFalse(hasattr(x, "foo"))
Guido van Rossum37202612001-08-09 19:45:21 +0000951
Georg Brandl48545522008-02-02 10:12:36 +0000952 class C1(object):
953 __slots__ = ['a']
954 x = C1()
955 self.assertFalse(hasattr(x, "__dict__"))
956 self.assertFalse(hasattr(x, "a"))
957 x.a = 1
958 self.assertEqual(x.a, 1)
959 x.a = None
960 self.assertEqual(x.a, None)
961 del x.a
962 self.assertFalse(hasattr(x, "a"))
Tim Peters6d6c1a32001-08-02 04:15:00 +0000963
Georg Brandl48545522008-02-02 10:12:36 +0000964 class C3(object):
965 __slots__ = ['a', 'b', 'c']
966 x = C3()
967 self.assertFalse(hasattr(x, "__dict__"))
968 self.assertFalse(hasattr(x, 'a'))
969 self.assertFalse(hasattr(x, 'b'))
970 self.assertFalse(hasattr(x, 'c'))
971 x.a = 1
972 x.b = 2
973 x.c = 3
974 self.assertEqual(x.a, 1)
975 self.assertEqual(x.b, 2)
976 self.assertEqual(x.c, 3)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000977
Georg Brandl48545522008-02-02 10:12:36 +0000978 class C4(object):
979 """Validate name mangling"""
980 __slots__ = ['__a']
981 def __init__(self, value):
982 self.__a = value
983 def get(self):
984 return self.__a
985 x = C4(5)
986 self.assertFalse(hasattr(x, '__dict__'))
987 self.assertFalse(hasattr(x, '__a'))
988 self.assertEqual(x.get(), 5)
989 try:
990 x.__a = 6
991 except AttributeError:
992 pass
993 else:
994 self.fail("Double underscored names not mangled")
Tim Peters6d6c1a32001-08-02 04:15:00 +0000995
Georg Brandl48545522008-02-02 10:12:36 +0000996 # Make sure slot names are proper identifiers
Žiga Seilnacht71436f02007-03-14 12:24:09 +0000997 try:
998 class C(object):
Georg Brandl48545522008-02-02 10:12:36 +0000999 __slots__ = [None]
Guido van Rossum843daa82001-09-18 20:04:26 +00001000 except TypeError:
1001 pass
1002 else:
Georg Brandl48545522008-02-02 10:12:36 +00001003 self.fail("[None] slots not caught")
Tim Peters66c1a522001-09-24 21:17:50 +00001004 try:
Georg Brandl48545522008-02-02 10:12:36 +00001005 class C(object):
1006 __slots__ = ["foo bar"]
1007 except TypeError:
Georg Brandl533ff6f2006-03-08 18:09:27 +00001008 pass
Georg Brandl48545522008-02-02 10:12:36 +00001009 else:
1010 self.fail("['foo bar'] slots not caught")
1011 try:
1012 class C(object):
1013 __slots__ = ["foo\0bar"]
1014 except TypeError:
1015 pass
1016 else:
1017 self.fail("['foo\\0bar'] slots not caught")
1018 try:
1019 class C(object):
1020 __slots__ = ["1"]
1021 except TypeError:
1022 pass
1023 else:
1024 self.fail("['1'] slots not caught")
1025 try:
1026 class C(object):
1027 __slots__ = [""]
1028 except TypeError:
1029 pass
1030 else:
1031 self.fail("[''] slots not caught")
1032 class C(object):
1033 __slots__ = ["a", "a_b", "_a", "A0123456789Z"]
1034 # XXX(nnorwitz): was there supposed to be something tested
1035 # from the class above?
Georg Brandl533ff6f2006-03-08 18:09:27 +00001036
Georg Brandl48545522008-02-02 10:12:36 +00001037 # Test a single string is not expanded as a sequence.
1038 class C(object):
1039 __slots__ = "abc"
1040 c = C()
1041 c.abc = 5
1042 self.assertEqual(c.abc, 5)
Georg Brandle9462c72006-08-04 18:03:37 +00001043
Georg Brandl48545522008-02-02 10:12:36 +00001044 # Test unicode slot names
1045 try:
1046 unicode
1047 except NameError:
1048 pass
1049 else:
1050 # Test a single unicode string is not expanded as a sequence.
1051 class C(object):
1052 __slots__ = unicode("abc")
1053 c = C()
1054 c.abc = 5
1055 self.assertEqual(c.abc, 5)
Georg Brandle9462c72006-08-04 18:03:37 +00001056
Georg Brandl48545522008-02-02 10:12:36 +00001057 # _unicode_to_string used to modify slots in certain circumstances
1058 slots = (unicode("foo"), unicode("bar"))
1059 class C(object):
1060 __slots__ = slots
1061 x = C()
1062 x.foo = 5
1063 self.assertEqual(x.foo, 5)
1064 self.assertEqual(type(slots[0]), unicode)
1065 # this used to leak references
Guido van Rossumd1ef7892007-11-10 22:12:24 +00001066 try:
Georg Brandl48545522008-02-02 10:12:36 +00001067 class C(object):
1068 __slots__ = [unichr(128)]
1069 except (TypeError, UnicodeEncodeError):
Guido van Rossumd1ef7892007-11-10 22:12:24 +00001070 pass
Tim Peters8fa45672001-09-13 21:01:29 +00001071 else:
Georg Brandl48545522008-02-02 10:12:36 +00001072 self.fail("[unichr(128)] slots not caught")
Tim Peters8fa45672001-09-13 21:01:29 +00001073
Georg Brandl48545522008-02-02 10:12:36 +00001074 # Test leaks
1075 class Counted(object):
1076 counter = 0 # counts the number of instances alive
1077 def __init__(self):
1078 Counted.counter += 1
1079 def __del__(self):
1080 Counted.counter -= 1
1081 class C(object):
1082 __slots__ = ['a', 'b', 'c']
Guido van Rossum8c842552002-03-14 23:05:54 +00001083 x = C()
Georg Brandl48545522008-02-02 10:12:36 +00001084 x.a = Counted()
1085 x.b = Counted()
1086 x.c = Counted()
1087 self.assertEqual(Counted.counter, 3)
1088 del x
1089 self.assertEqual(Counted.counter, 0)
1090 class D(C):
1091 pass
Guido van Rossum8c842552002-03-14 23:05:54 +00001092 x = D()
Georg Brandl48545522008-02-02 10:12:36 +00001093 x.a = Counted()
1094 x.z = Counted()
1095 self.assertEqual(Counted.counter, 2)
1096 del x
1097 self.assertEqual(Counted.counter, 0)
1098 class E(D):
1099 __slots__ = ['e']
Guido van Rossum3f50cdc2003-02-10 21:31:27 +00001100 x = E()
Georg Brandl48545522008-02-02 10:12:36 +00001101 x.a = Counted()
1102 x.z = Counted()
1103 x.e = Counted()
1104 self.assertEqual(Counted.counter, 3)
1105 del x
1106 self.assertEqual(Counted.counter, 0)
Guido van Rossum8c842552002-03-14 23:05:54 +00001107
Georg Brandl48545522008-02-02 10:12:36 +00001108 # Test cyclical leaks [SF bug 519621]
1109 class F(object):
1110 __slots__ = ['a', 'b']
1111 log = []
1112 s = F()
1113 s.a = [Counted(), s]
1114 self.assertEqual(Counted.counter, 1)
1115 s = None
1116 import gc
1117 gc.collect()
1118 self.assertEqual(Counted.counter, 0)
Guido van Rossum6cef6d52001-09-28 18:13:29 +00001119
Georg Brandl48545522008-02-02 10:12:36 +00001120 # Test lookup leaks [SF bug 572567]
1121 import sys,gc
1122 class G(object):
1123 def __cmp__(self, other):
1124 return 0
Nick Coghlan48361f52008-08-11 15:45:58 +00001125 __hash__ = None # Silence Py3k warning
Georg Brandl48545522008-02-02 10:12:36 +00001126 g = G()
1127 orig_objects = len(gc.get_objects())
1128 for i in xrange(10):
1129 g==g
1130 new_objects = len(gc.get_objects())
1131 self.assertEqual(orig_objects, new_objects)
1132 class H(object):
1133 __slots__ = ['a', 'b']
1134 def __init__(self):
1135 self.a = 1
1136 self.b = 2
1137 def __del__(self_):
1138 self.assertEqual(self_.a, 1)
1139 self.assertEqual(self_.b, 2)
Georg Brandl4aef7032008-11-07 08:56:27 +00001140 with test_support.captured_output('stderr') as s:
1141 h = H()
Georg Brandl48545522008-02-02 10:12:36 +00001142 del h
Georg Brandl4aef7032008-11-07 08:56:27 +00001143 self.assertEqual(s.getvalue(), '')
Guido van Rossum6cef6d52001-09-28 18:13:29 +00001144
Georg Brandl48545522008-02-02 10:12:36 +00001145 def test_slots_special(self):
1146 # Testing __dict__ and __weakref__ in __slots__...
1147 class D(object):
1148 __slots__ = ["__dict__"]
1149 a = D()
1150 self.assert_(hasattr(a, "__dict__"))
1151 self.assertFalse(hasattr(a, "__weakref__"))
1152 a.foo = 42
1153 self.assertEqual(a.__dict__, {"foo": 42})
Guido van Rossum6cef6d52001-09-28 18:13:29 +00001154
Georg Brandl48545522008-02-02 10:12:36 +00001155 class W(object):
1156 __slots__ = ["__weakref__"]
1157 a = W()
1158 self.assert_(hasattr(a, "__weakref__"))
1159 self.assertFalse(hasattr(a, "__dict__"))
1160 try:
1161 a.foo = 42
1162 except AttributeError:
1163 pass
1164 else:
1165 self.fail("shouldn't be allowed to set a.foo")
1166
1167 class C1(W, D):
1168 __slots__ = []
1169 a = C1()
1170 self.assert_(hasattr(a, "__dict__"))
1171 self.assert_(hasattr(a, "__weakref__"))
1172 a.foo = 42
1173 self.assertEqual(a.__dict__, {"foo": 42})
1174
1175 class C2(D, W):
1176 __slots__ = []
1177 a = C2()
1178 self.assert_(hasattr(a, "__dict__"))
1179 self.assert_(hasattr(a, "__weakref__"))
1180 a.foo = 42
1181 self.assertEqual(a.__dict__, {"foo": 42})
1182
Amaury Forgeot d'Arc60d6c7f2008-02-15 21:22:45 +00001183 def test_slots_descriptor(self):
1184 # Issue2115: slot descriptors did not correctly check
1185 # the type of the given object
1186 import abc
1187 class MyABC:
1188 __metaclass__ = abc.ABCMeta
1189 __slots__ = "a"
1190
1191 class Unrelated(object):
1192 pass
1193 MyABC.register(Unrelated)
1194
1195 u = Unrelated()
1196 self.assert_(isinstance(u, MyABC))
1197
1198 # This used to crash
1199 self.assertRaises(TypeError, MyABC.a.__set__, u, 3)
1200
Georg Brandl48545522008-02-02 10:12:36 +00001201 def test_dynamics(self):
1202 # Testing class attribute propagation...
1203 class D(object):
1204 pass
1205 class E(D):
1206 pass
1207 class F(D):
1208 pass
1209 D.foo = 1
1210 self.assertEqual(D.foo, 1)
1211 # Test that dynamic attributes are inherited
1212 self.assertEqual(E.foo, 1)
1213 self.assertEqual(F.foo, 1)
1214 # Test dynamic instances
1215 class C(object):
1216 pass
1217 a = C()
1218 self.assertFalse(hasattr(a, "foobar"))
1219 C.foobar = 2
1220 self.assertEqual(a.foobar, 2)
1221 C.method = lambda self: 42
1222 self.assertEqual(a.method(), 42)
1223 C.__repr__ = lambda self: "C()"
1224 self.assertEqual(repr(a), "C()")
1225 C.__int__ = lambda self: 100
1226 self.assertEqual(int(a), 100)
1227 self.assertEqual(a.foobar, 2)
1228 self.assertFalse(hasattr(a, "spam"))
1229 def mygetattr(self, name):
1230 if name == "spam":
1231 return "spam"
1232 raise AttributeError
1233 C.__getattr__ = mygetattr
1234 self.assertEqual(a.spam, "spam")
1235 a.new = 12
1236 self.assertEqual(a.new, 12)
1237 def mysetattr(self, name, value):
1238 if name == "spam":
1239 raise AttributeError
1240 return object.__setattr__(self, name, value)
1241 C.__setattr__ = mysetattr
1242 try:
1243 a.spam = "not spam"
1244 except AttributeError:
1245 pass
1246 else:
1247 self.fail("expected AttributeError")
1248 self.assertEqual(a.spam, "spam")
1249 class D(C):
1250 pass
1251 d = D()
1252 d.foo = 1
1253 self.assertEqual(d.foo, 1)
1254
1255 # Test handling of int*seq and seq*int
1256 class I(int):
1257 pass
1258 self.assertEqual("a"*I(2), "aa")
1259 self.assertEqual(I(2)*"a", "aa")
1260 self.assertEqual(2*I(3), 6)
1261 self.assertEqual(I(3)*2, 6)
1262 self.assertEqual(I(3)*I(2), 6)
1263
1264 # Test handling of long*seq and seq*long
1265 class L(long):
1266 pass
1267 self.assertEqual("a"*L(2L), "aa")
1268 self.assertEqual(L(2L)*"a", "aa")
1269 self.assertEqual(2*L(3), 6)
1270 self.assertEqual(L(3)*2, 6)
1271 self.assertEqual(L(3)*L(2), 6)
1272
1273 # Test comparison of classes with dynamic metaclasses
1274 class dynamicmetaclass(type):
1275 pass
1276 class someclass:
1277 __metaclass__ = dynamicmetaclass
1278 self.assertNotEqual(someclass, object)
1279
1280 def test_errors(self):
1281 # Testing errors...
1282 try:
1283 class C(list, dict):
1284 pass
1285 except TypeError:
1286 pass
1287 else:
1288 self.fail("inheritance from both list and dict should be illegal")
1289
1290 try:
1291 class C(object, None):
1292 pass
1293 except TypeError:
1294 pass
1295 else:
1296 self.fail("inheritance from non-type should be illegal")
1297 class Classic:
1298 pass
1299
1300 try:
1301 class C(type(len)):
1302 pass
1303 except TypeError:
1304 pass
1305 else:
1306 self.fail("inheritance from CFunction should be illegal")
1307
1308 try:
1309 class C(object):
1310 __slots__ = 1
1311 except TypeError:
1312 pass
1313 else:
1314 self.fail("__slots__ = 1 should be illegal")
1315
1316 try:
1317 class C(object):
1318 __slots__ = [1]
1319 except TypeError:
1320 pass
1321 else:
1322 self.fail("__slots__ = [1] should be illegal")
1323
1324 class M1(type):
1325 pass
1326 class M2(type):
1327 pass
1328 class A1(object):
1329 __metaclass__ = M1
1330 class A2(object):
1331 __metaclass__ = M2
1332 try:
1333 class B(A1, A2):
1334 pass
1335 except TypeError:
1336 pass
1337 else:
1338 self.fail("finding the most derived metaclass should have failed")
1339
1340 def test_classmethods(self):
1341 # Testing class methods...
1342 class C(object):
1343 def foo(*a): return a
1344 goo = classmethod(foo)
1345 c = C()
1346 self.assertEqual(C.goo(1), (C, 1))
1347 self.assertEqual(c.goo(1), (C, 1))
1348 self.assertEqual(c.foo(1), (c, 1))
1349 class D(C):
1350 pass
1351 d = D()
1352 self.assertEqual(D.goo(1), (D, 1))
1353 self.assertEqual(d.goo(1), (D, 1))
1354 self.assertEqual(d.foo(1), (d, 1))
1355 self.assertEqual(D.foo(d, 1), (d, 1))
1356 # Test for a specific crash (SF bug 528132)
1357 def f(cls, arg): return (cls, arg)
1358 ff = classmethod(f)
1359 self.assertEqual(ff.__get__(0, int)(42), (int, 42))
1360 self.assertEqual(ff.__get__(0)(42), (int, 42))
1361
1362 # Test super() with classmethods (SF bug 535444)
1363 self.assertEqual(C.goo.im_self, C)
1364 self.assertEqual(D.goo.im_self, D)
1365 self.assertEqual(super(D,D).goo.im_self, D)
1366 self.assertEqual(super(D,d).goo.im_self, D)
1367 self.assertEqual(super(D,D).goo(), (D,))
1368 self.assertEqual(super(D,d).goo(), (D,))
1369
1370 # Verify that argument is checked for callability (SF bug 753451)
1371 try:
1372 classmethod(1).__get__(1)
1373 except TypeError:
1374 pass
1375 else:
1376 self.fail("classmethod should check for callability")
1377
1378 # Verify that classmethod() doesn't allow keyword args
1379 try:
1380 classmethod(f, kw=1)
1381 except TypeError:
1382 pass
1383 else:
1384 self.fail("classmethod shouldn't accept keyword args")
1385
1386 def test_classmethods_in_c(self):
1387 # Testing C-based class methods...
1388 import xxsubtype as spam
1389 a = (1, 2, 3)
1390 d = {'abc': 123}
1391 x, a1, d1 = spam.spamlist.classmeth(*a, **d)
1392 self.assertEqual(x, spam.spamlist)
1393 self.assertEqual(a, a1)
1394 self.assertEqual(d, d1)
1395 x, a1, d1 = spam.spamlist().classmeth(*a, **d)
1396 self.assertEqual(x, spam.spamlist)
1397 self.assertEqual(a, a1)
1398 self.assertEqual(d, d1)
1399
1400 def test_staticmethods(self):
1401 # Testing static methods...
1402 class C(object):
1403 def foo(*a): return a
1404 goo = staticmethod(foo)
1405 c = C()
1406 self.assertEqual(C.goo(1), (1,))
1407 self.assertEqual(c.goo(1), (1,))
1408 self.assertEqual(c.foo(1), (c, 1,))
1409 class D(C):
1410 pass
1411 d = D()
1412 self.assertEqual(D.goo(1), (1,))
1413 self.assertEqual(d.goo(1), (1,))
1414 self.assertEqual(d.foo(1), (d, 1))
1415 self.assertEqual(D.foo(d, 1), (d, 1))
1416
1417 def test_staticmethods_in_c(self):
1418 # Testing C-based static methods...
1419 import xxsubtype as spam
1420 a = (1, 2, 3)
1421 d = {"abc": 123}
1422 x, a1, d1 = spam.spamlist.staticmeth(*a, **d)
1423 self.assertEqual(x, None)
1424 self.assertEqual(a, a1)
1425 self.assertEqual(d, d1)
1426 x, a1, d2 = spam.spamlist().staticmeth(*a, **d)
1427 self.assertEqual(x, None)
1428 self.assertEqual(a, a1)
1429 self.assertEqual(d, d1)
1430
1431 def test_classic(self):
1432 # Testing classic classes...
1433 class C:
1434 def foo(*a): return a
1435 goo = classmethod(foo)
1436 c = C()
1437 self.assertEqual(C.goo(1), (C, 1))
1438 self.assertEqual(c.goo(1), (C, 1))
1439 self.assertEqual(c.foo(1), (c, 1))
1440 class D(C):
1441 pass
1442 d = D()
1443 self.assertEqual(D.goo(1), (D, 1))
1444 self.assertEqual(d.goo(1), (D, 1))
1445 self.assertEqual(d.foo(1), (d, 1))
1446 self.assertEqual(D.foo(d, 1), (d, 1))
1447 class E: # *not* subclassing from C
1448 foo = C.foo
1449 self.assertEqual(E().foo, C.foo) # i.e., unbound
1450 self.assert_(repr(C.foo.__get__(C())).startswith("<bound method "))
1451
1452 def test_compattr(self):
1453 # Testing computed attributes...
1454 class C(object):
1455 class computed_attribute(object):
1456 def __init__(self, get, set=None, delete=None):
1457 self.__get = get
1458 self.__set = set
1459 self.__delete = delete
1460 def __get__(self, obj, type=None):
1461 return self.__get(obj)
1462 def __set__(self, obj, value):
1463 return self.__set(obj, value)
1464 def __delete__(self, obj):
1465 return self.__delete(obj)
1466 def __init__(self):
1467 self.__x = 0
1468 def __get_x(self):
1469 x = self.__x
1470 self.__x = x+1
1471 return x
1472 def __set_x(self, x):
1473 self.__x = x
1474 def __delete_x(self):
1475 del self.__x
1476 x = computed_attribute(__get_x, __set_x, __delete_x)
1477 a = C()
1478 self.assertEqual(a.x, 0)
1479 self.assertEqual(a.x, 1)
1480 a.x = 10
1481 self.assertEqual(a.x, 10)
1482 self.assertEqual(a.x, 11)
1483 del a.x
1484 self.assertEqual(hasattr(a, 'x'), 0)
1485
1486 def test_newslots(self):
1487 # Testing __new__ slot override...
1488 class C(list):
1489 def __new__(cls):
1490 self = list.__new__(cls)
1491 self.foo = 1
1492 return self
1493 def __init__(self):
1494 self.foo = self.foo + 2
1495 a = C()
1496 self.assertEqual(a.foo, 3)
1497 self.assertEqual(a.__class__, C)
1498 class D(C):
1499 pass
1500 b = D()
1501 self.assertEqual(b.foo, 3)
1502 self.assertEqual(b.__class__, D)
1503
1504 def test_altmro(self):
1505 # Testing mro() and overriding it...
1506 class A(object):
1507 def f(self): return "A"
1508 class B(A):
1509 pass
1510 class C(A):
1511 def f(self): return "C"
1512 class D(B, C):
1513 pass
1514 self.assertEqual(D.mro(), [D, B, C, A, object])
1515 self.assertEqual(D.__mro__, (D, B, C, A, object))
1516 self.assertEqual(D().f(), "C")
1517
1518 class PerverseMetaType(type):
1519 def mro(cls):
1520 L = type.mro(cls)
1521 L.reverse()
1522 return L
1523 class X(D,B,C,A):
1524 __metaclass__ = PerverseMetaType
1525 self.assertEqual(X.__mro__, (object, A, C, B, D, X))
1526 self.assertEqual(X().f(), "A")
1527
1528 try:
1529 class X(object):
1530 class __metaclass__(type):
1531 def mro(self):
1532 return [self, dict, object]
1533 except TypeError:
1534 pass
1535 else:
1536 self.fail("devious mro() return not caught")
1537
1538 try:
1539 class X(object):
1540 class __metaclass__(type):
1541 def mro(self):
1542 return [1]
1543 except TypeError:
1544 pass
1545 else:
1546 self.fail("non-class mro() return not caught")
1547
1548 try:
1549 class X(object):
1550 class __metaclass__(type):
1551 def mro(self):
1552 return 1
1553 except TypeError:
1554 pass
1555 else:
1556 self.fail("non-sequence mro() return not caught")
1557
1558 def test_overloading(self):
1559 # Testing operator overloading...
1560
1561 class B(object):
1562 "Intermediate class because object doesn't have a __setattr__"
1563
1564 class C(B):
1565 def __getattr__(self, name):
1566 if name == "foo":
1567 return ("getattr", name)
1568 else:
1569 raise AttributeError
1570 def __setattr__(self, name, value):
1571 if name == "foo":
1572 self.setattr = (name, value)
1573 else:
1574 return B.__setattr__(self, name, value)
1575 def __delattr__(self, name):
1576 if name == "foo":
1577 self.delattr = name
1578 else:
1579 return B.__delattr__(self, name)
1580
1581 def __getitem__(self, key):
1582 return ("getitem", key)
1583 def __setitem__(self, key, value):
1584 self.setitem = (key, value)
1585 def __delitem__(self, key):
1586 self.delitem = key
1587
1588 def __getslice__(self, i, j):
1589 return ("getslice", i, j)
1590 def __setslice__(self, i, j, value):
1591 self.setslice = (i, j, value)
1592 def __delslice__(self, i, j):
1593 self.delslice = (i, j)
1594
1595 a = C()
1596 self.assertEqual(a.foo, ("getattr", "foo"))
1597 a.foo = 12
1598 self.assertEqual(a.setattr, ("foo", 12))
1599 del a.foo
1600 self.assertEqual(a.delattr, "foo")
1601
1602 self.assertEqual(a[12], ("getitem", 12))
1603 a[12] = 21
1604 self.assertEqual(a.setitem, (12, 21))
1605 del a[12]
1606 self.assertEqual(a.delitem, 12)
1607
1608 self.assertEqual(a[0:10], ("getslice", 0, 10))
1609 a[0:10] = "foo"
1610 self.assertEqual(a.setslice, (0, 10, "foo"))
1611 del a[0:10]
1612 self.assertEqual(a.delslice, (0, 10))
1613
1614 def test_methods(self):
1615 # Testing methods...
1616 class C(object):
1617 def __init__(self, x):
1618 self.x = x
1619 def foo(self):
1620 return self.x
1621 c1 = C(1)
1622 self.assertEqual(c1.foo(), 1)
1623 class D(C):
1624 boo = C.foo
1625 goo = c1.foo
1626 d2 = D(2)
1627 self.assertEqual(d2.foo(), 2)
1628 self.assertEqual(d2.boo(), 2)
1629 self.assertEqual(d2.goo(), 1)
1630 class E(object):
1631 foo = C.foo
1632 self.assertEqual(E().foo, C.foo) # i.e., unbound
1633 self.assert_(repr(C.foo.__get__(C(1))).startswith("<bound method "))
1634
1635 def test_specials(self):
1636 # Testing special operators...
1637 # Test operators like __hash__ for which a built-in default exists
1638
1639 # Test the default behavior for static classes
1640 class C(object):
1641 def __getitem__(self, i):
1642 if 0 <= i < 10: return i
1643 raise IndexError
1644 c1 = C()
1645 c2 = C()
1646 self.assert_(not not c1) # What?
1647 self.assertNotEqual(id(c1), id(c2))
1648 hash(c1)
1649 hash(c2)
1650 self.assertEqual(cmp(c1, c2), cmp(id(c1), id(c2)))
1651 self.assertEqual(c1, c1)
1652 self.assert_(c1 != c2)
1653 self.assert_(not c1 != c1)
1654 self.assert_(not c1 == c2)
1655 # Note that the module name appears in str/repr, and that varies
1656 # depending on whether this test is run standalone or from a framework.
1657 self.assert_(str(c1).find('C object at ') >= 0)
1658 self.assertEqual(str(c1), repr(c1))
1659 self.assert_(-1 not in c1)
1660 for i in range(10):
1661 self.assert_(i in c1)
1662 self.assertFalse(10 in c1)
1663 # Test the default behavior for dynamic classes
1664 class D(object):
1665 def __getitem__(self, i):
1666 if 0 <= i < 10: return i
1667 raise IndexError
1668 d1 = D()
1669 d2 = D()
1670 self.assert_(not not d1)
1671 self.assertNotEqual(id(d1), id(d2))
1672 hash(d1)
1673 hash(d2)
1674 self.assertEqual(cmp(d1, d2), cmp(id(d1), id(d2)))
1675 self.assertEqual(d1, d1)
1676 self.assertNotEqual(d1, d2)
1677 self.assert_(not d1 != d1)
1678 self.assert_(not d1 == d2)
1679 # Note that the module name appears in str/repr, and that varies
1680 # depending on whether this test is run standalone or from a framework.
1681 self.assert_(str(d1).find('D object at ') >= 0)
1682 self.assertEqual(str(d1), repr(d1))
1683 self.assert_(-1 not in d1)
1684 for i in range(10):
1685 self.assert_(i in d1)
1686 self.assertFalse(10 in d1)
1687 # Test overridden behavior for static classes
1688 class Proxy(object):
1689 def __init__(self, x):
1690 self.x = x
1691 def __nonzero__(self):
1692 return not not self.x
1693 def __hash__(self):
1694 return hash(self.x)
1695 def __eq__(self, other):
1696 return self.x == other
1697 def __ne__(self, other):
1698 return self.x != other
1699 def __cmp__(self, other):
1700 return cmp(self.x, other.x)
1701 def __str__(self):
1702 return "Proxy:%s" % self.x
1703 def __repr__(self):
1704 return "Proxy(%r)" % self.x
1705 def __contains__(self, value):
1706 return value in self.x
1707 p0 = Proxy(0)
1708 p1 = Proxy(1)
1709 p_1 = Proxy(-1)
1710 self.assertFalse(p0)
1711 self.assert_(not not p1)
1712 self.assertEqual(hash(p0), hash(0))
1713 self.assertEqual(p0, p0)
1714 self.assertNotEqual(p0, p1)
1715 self.assert_(not p0 != p0)
1716 self.assertEqual(not p0, p1)
1717 self.assertEqual(cmp(p0, p1), -1)
1718 self.assertEqual(cmp(p0, p0), 0)
1719 self.assertEqual(cmp(p0, p_1), 1)
1720 self.assertEqual(str(p0), "Proxy:0")
1721 self.assertEqual(repr(p0), "Proxy(0)")
1722 p10 = Proxy(range(10))
1723 self.assertFalse(-1 in p10)
1724 for i in range(10):
1725 self.assert_(i in p10)
1726 self.assertFalse(10 in p10)
1727 # Test overridden behavior for dynamic classes
1728 class DProxy(object):
1729 def __init__(self, x):
1730 self.x = x
1731 def __nonzero__(self):
1732 return not not self.x
1733 def __hash__(self):
1734 return hash(self.x)
1735 def __eq__(self, other):
1736 return self.x == other
1737 def __ne__(self, other):
1738 return self.x != other
1739 def __cmp__(self, other):
1740 return cmp(self.x, other.x)
1741 def __str__(self):
1742 return "DProxy:%s" % self.x
1743 def __repr__(self):
1744 return "DProxy(%r)" % self.x
1745 def __contains__(self, value):
1746 return value in self.x
1747 p0 = DProxy(0)
1748 p1 = DProxy(1)
1749 p_1 = DProxy(-1)
1750 self.assertFalse(p0)
1751 self.assert_(not not p1)
1752 self.assertEqual(hash(p0), hash(0))
1753 self.assertEqual(p0, p0)
1754 self.assertNotEqual(p0, p1)
1755 self.assertNotEqual(not p0, p0)
1756 self.assertEqual(not p0, p1)
1757 self.assertEqual(cmp(p0, p1), -1)
1758 self.assertEqual(cmp(p0, p0), 0)
1759 self.assertEqual(cmp(p0, p_1), 1)
1760 self.assertEqual(str(p0), "DProxy:0")
1761 self.assertEqual(repr(p0), "DProxy(0)")
1762 p10 = DProxy(range(10))
1763 self.assertFalse(-1 in p10)
1764 for i in range(10):
1765 self.assert_(i in p10)
1766 self.assertFalse(10 in p10)
1767
1768 # Safety test for __cmp__
1769 def unsafecmp(a, b):
1770 try:
1771 a.__class__.__cmp__(a, b)
1772 except TypeError:
1773 pass
Guido van Rossum4bb1e362001-09-28 23:49:48 +00001774 else:
Georg Brandl48545522008-02-02 10:12:36 +00001775 self.fail("shouldn't allow %s.__cmp__(%r, %r)" % (
1776 a.__class__, a, b))
1777
1778 unsafecmp(u"123", "123")
1779 unsafecmp("123", u"123")
1780 unsafecmp(1, 1.0)
1781 unsafecmp(1.0, 1)
1782 unsafecmp(1, 1L)
1783 unsafecmp(1L, 1)
1784
1785 def test_recursions(self):
1786 # Testing recursion checks ...
1787 class Letter(str):
1788 def __new__(cls, letter):
1789 if letter == 'EPS':
1790 return str.__new__(cls)
1791 return str.__new__(cls, letter)
1792 def __str__(self):
1793 if not self:
1794 return 'EPS'
1795 return self
1796 # sys.stdout needs to be the original to trigger the recursion bug
1797 import sys
1798 test_stdout = sys.stdout
1799 sys.stdout = test_support.get_original_stdout()
1800 try:
1801 # nothing should actually be printed, this should raise an exception
1802 print Letter('w')
1803 except RuntimeError:
1804 pass
1805 else:
1806 self.fail("expected a RuntimeError for print recursion")
1807 finally:
1808 sys.stdout = test_stdout
1809
1810 # Bug #1202533.
1811 class A(object):
1812 pass
1813 A.__mul__ = types.MethodType(lambda self, x: self * x, None, A)
1814 try:
1815 A()*2
1816 except RuntimeError:
1817 pass
1818 else:
1819 self.fail("expected a RuntimeError")
1820
1821 def test_weakrefs(self):
1822 # Testing weak references...
1823 import weakref
1824 class C(object):
1825 pass
1826 c = C()
1827 r = weakref.ref(c)
1828 self.assertEqual(r(), c)
1829 del c
1830 self.assertEqual(r(), None)
1831 del r
1832 class NoWeak(object):
1833 __slots__ = ['foo']
1834 no = NoWeak()
1835 try:
1836 weakref.ref(no)
1837 except TypeError, msg:
1838 self.assert_(str(msg).find("weak reference") >= 0)
1839 else:
1840 self.fail("weakref.ref(no) should be illegal")
1841 class Weak(object):
1842 __slots__ = ['foo', '__weakref__']
1843 yes = Weak()
1844 r = weakref.ref(yes)
1845 self.assertEqual(r(), yes)
1846 del yes
1847 self.assertEqual(r(), None)
1848 del r
1849
1850 def test_properties(self):
1851 # Testing property...
1852 class C(object):
1853 def getx(self):
1854 return self.__x
1855 def setx(self, value):
1856 self.__x = value
1857 def delx(self):
1858 del self.__x
1859 x = property(getx, setx, delx, doc="I'm the x property.")
1860 a = C()
1861 self.assertFalse(hasattr(a, "x"))
1862 a.x = 42
1863 self.assertEqual(a._C__x, 42)
1864 self.assertEqual(a.x, 42)
1865 del a.x
1866 self.assertFalse(hasattr(a, "x"))
1867 self.assertFalse(hasattr(a, "_C__x"))
1868 C.x.__set__(a, 100)
1869 self.assertEqual(C.x.__get__(a), 100)
1870 C.x.__delete__(a)
1871 self.assertFalse(hasattr(a, "x"))
1872
1873 raw = C.__dict__['x']
1874 self.assert_(isinstance(raw, property))
1875
1876 attrs = dir(raw)
1877 self.assert_("__doc__" in attrs)
1878 self.assert_("fget" in attrs)
1879 self.assert_("fset" in attrs)
1880 self.assert_("fdel" in attrs)
1881
1882 self.assertEqual(raw.__doc__, "I'm the x property.")
1883 self.assert_(raw.fget is C.__dict__['getx'])
1884 self.assert_(raw.fset is C.__dict__['setx'])
1885 self.assert_(raw.fdel is C.__dict__['delx'])
1886
1887 for attr in "__doc__", "fget", "fset", "fdel":
1888 try:
1889 setattr(raw, attr, 42)
1890 except TypeError, msg:
1891 if str(msg).find('readonly') < 0:
1892 self.fail("when setting readonly attr %r on a property, "
1893 "got unexpected TypeError msg %r" % (attr, str(msg)))
Guido van Rossum4bb1e362001-09-28 23:49:48 +00001894 else:
Georg Brandl48545522008-02-02 10:12:36 +00001895 self.fail("expected TypeError from trying to set readonly %r "
1896 "attr on a property" % attr)
Tim Peters2f93e282001-10-04 05:27:00 +00001897
Georg Brandl48545522008-02-02 10:12:36 +00001898 class D(object):
1899 __getitem__ = property(lambda s: 1/0)
Guido van Rossum4bb1e362001-09-28 23:49:48 +00001900
Georg Brandl48545522008-02-02 10:12:36 +00001901 d = D()
1902 try:
1903 for i in d:
1904 str(i)
1905 except ZeroDivisionError:
Walter Dörwalddbd2d252002-03-25 18:36:32 +00001906 pass
Georg Brandl48545522008-02-02 10:12:36 +00001907 else:
1908 self.fail("expected ZeroDivisionError from bad property")
Walter Dörwalddbd2d252002-03-25 18:36:32 +00001909
Georg Brandl48545522008-02-02 10:12:36 +00001910 class E(object):
1911 def getter(self):
1912 "getter method"
1913 return 0
1914 def setter(self_, value):
1915 "setter method"
1916 pass
1917 prop = property(getter)
1918 self.assertEqual(prop.__doc__, "getter method")
1919 prop2 = property(fset=setter)
1920 self.assertEqual(prop2.__doc__, None)
1921
1922 # this segfaulted in 2.5b2
1923 try:
1924 import _testcapi
1925 except ImportError:
Walter Dörwalddbd2d252002-03-25 18:36:32 +00001926 pass
Georg Brandl48545522008-02-02 10:12:36 +00001927 else:
1928 class X(object):
1929 p = property(_testcapi.test_with_docstring)
Walter Dörwalddbd2d252002-03-25 18:36:32 +00001930
Georg Brandl48545522008-02-02 10:12:36 +00001931 def test_properties_plus(self):
1932 class C(object):
1933 foo = property(doc="hello")
1934 @foo.getter
1935 def foo(self):
1936 return self._foo
1937 @foo.setter
1938 def foo(self, value):
1939 self._foo = abs(value)
1940 @foo.deleter
1941 def foo(self):
1942 del self._foo
1943 c = C()
1944 self.assertEqual(C.foo.__doc__, "hello")
1945 self.assertFalse(hasattr(c, "foo"))
1946 c.foo = -42
1947 self.assert_(hasattr(c, '_foo'))
1948 self.assertEqual(c._foo, 42)
1949 self.assertEqual(c.foo, 42)
1950 del c.foo
1951 self.assertFalse(hasattr(c, '_foo'))
1952 self.assertFalse(hasattr(c, "foo"))
Walter Dörwalddbd2d252002-03-25 18:36:32 +00001953
Georg Brandl48545522008-02-02 10:12:36 +00001954 class D(C):
1955 @C.foo.deleter
1956 def foo(self):
1957 try:
1958 del self._foo
1959 except AttributeError:
1960 pass
1961 d = D()
1962 d.foo = 24
1963 self.assertEqual(d.foo, 24)
1964 del d.foo
1965 del d.foo
Guido van Rossum8ace1ab2002-04-06 01:05:01 +00001966
Georg Brandl48545522008-02-02 10:12:36 +00001967 class E(object):
1968 @property
1969 def foo(self):
1970 return self._foo
1971 @foo.setter
1972 def foo(self, value):
1973 raise RuntimeError
1974 @foo.setter
1975 def foo(self, value):
1976 self._foo = abs(value)
1977 @foo.deleter
1978 def foo(self, value=None):
1979 del self._foo
Guido van Rossume8fc6402002-04-16 16:44:51 +00001980
Georg Brandl48545522008-02-02 10:12:36 +00001981 e = E()
1982 e.foo = -42
1983 self.assertEqual(e.foo, 42)
1984 del e.foo
Guido van Rossumd99b3e72002-04-18 00:27:33 +00001985
Georg Brandl48545522008-02-02 10:12:36 +00001986 class F(E):
1987 @E.foo.deleter
1988 def foo(self):
1989 del self._foo
1990 @foo.setter
1991 def foo(self, value):
1992 self._foo = max(0, value)
1993 f = F()
1994 f.foo = -10
1995 self.assertEqual(f.foo, 0)
1996 del f.foo
Guido van Rossuma48cb8f2002-06-06 17:53:03 +00001997
Georg Brandl48545522008-02-02 10:12:36 +00001998 def test_dict_constructors(self):
1999 # Testing dict constructor ...
2000 d = dict()
2001 self.assertEqual(d, {})
2002 d = dict({})
2003 self.assertEqual(d, {})
2004 d = dict({1: 2, 'a': 'b'})
2005 self.assertEqual(d, {1: 2, 'a': 'b'})
2006 self.assertEqual(d, dict(d.items()))
2007 self.assertEqual(d, dict(d.iteritems()))
2008 d = dict({'one':1, 'two':2})
2009 self.assertEqual(d, dict(one=1, two=2))
2010 self.assertEqual(d, dict(**d))
2011 self.assertEqual(d, dict({"one": 1}, two=2))
2012 self.assertEqual(d, dict([("two", 2)], one=1))
2013 self.assertEqual(d, dict([("one", 100), ("two", 200)], **d))
2014 self.assertEqual(d, dict(**d))
Guido van Rossum09638c12002-06-13 19:17:46 +00002015
Georg Brandl48545522008-02-02 10:12:36 +00002016 for badarg in 0, 0L, 0j, "0", [0], (0,):
2017 try:
2018 dict(badarg)
2019 except TypeError:
2020 pass
2021 except ValueError:
2022 if badarg == "0":
2023 # It's a sequence, and its elements are also sequences (gotta
2024 # love strings <wink>), but they aren't of length 2, so this
2025 # one seemed better as a ValueError than a TypeError.
2026 pass
2027 else:
2028 self.fail("no TypeError from dict(%r)" % badarg)
Michael W. Hudson98bbc492002-11-26 14:47:27 +00002029 else:
Georg Brandl48545522008-02-02 10:12:36 +00002030 self.fail("no TypeError from dict(%r)" % badarg)
Michael W. Hudson98bbc492002-11-26 14:47:27 +00002031
Georg Brandl48545522008-02-02 10:12:36 +00002032 try:
2033 dict({}, {})
2034 except TypeError:
2035 pass
2036 else:
2037 self.fail("no TypeError from dict({}, {})")
Michael W. Hudson98bbc492002-11-26 14:47:27 +00002038
Georg Brandl48545522008-02-02 10:12:36 +00002039 class Mapping:
2040 # Lacks a .keys() method; will be added later.
2041 dict = {1:2, 3:4, 'a':1j}
Michael W. Hudson98bbc492002-11-26 14:47:27 +00002042
Georg Brandl48545522008-02-02 10:12:36 +00002043 try:
2044 dict(Mapping())
2045 except TypeError:
2046 pass
2047 else:
2048 self.fail("no TypeError from dict(incomplete mapping)")
Michael W. Hudson98bbc492002-11-26 14:47:27 +00002049
Georg Brandl48545522008-02-02 10:12:36 +00002050 Mapping.keys = lambda self: self.dict.keys()
2051 Mapping.__getitem__ = lambda self, i: self.dict[i]
2052 d = dict(Mapping())
2053 self.assertEqual(d, Mapping.dict)
Michael W. Hudsonf3904422006-11-23 13:54:04 +00002054
Georg Brandl48545522008-02-02 10:12:36 +00002055 # Init from sequence of iterable objects, each producing a 2-sequence.
2056 class AddressBookEntry:
2057 def __init__(self, first, last):
2058 self.first = first
2059 self.last = last
2060 def __iter__(self):
2061 return iter([self.first, self.last])
Michael W. Hudson98bbc492002-11-26 14:47:27 +00002062
Georg Brandl48545522008-02-02 10:12:36 +00002063 d = dict([AddressBookEntry('Tim', 'Warsaw'),
2064 AddressBookEntry('Barry', 'Peters'),
2065 AddressBookEntry('Tim', 'Peters'),
2066 AddressBookEntry('Barry', 'Warsaw')])
2067 self.assertEqual(d, {'Barry': 'Warsaw', 'Tim': 'Peters'})
Guido van Rossum3bbc0ee2002-12-13 17:49:38 +00002068
Georg Brandl48545522008-02-02 10:12:36 +00002069 d = dict(zip(range(4), range(1, 5)))
2070 self.assertEqual(d, dict([(i, i+1) for i in range(4)]))
Michael W. Hudson98bbc492002-11-26 14:47:27 +00002071
Georg Brandl48545522008-02-02 10:12:36 +00002072 # Bad sequence lengths.
2073 for bad in [('tooshort',)], [('too', 'long', 'by 1')]:
2074 try:
2075 dict(bad)
2076 except ValueError:
2077 pass
Michael W. Hudson586da8f2002-11-27 15:20:19 +00002078 else:
Georg Brandl48545522008-02-02 10:12:36 +00002079 self.fail("no ValueError from dict(%r)" % bad)
2080
2081 def test_dir(self):
2082 # Testing dir() ...
2083 junk = 12
2084 self.assertEqual(dir(), ['junk', 'self'])
2085 del junk
2086
2087 # Just make sure these don't blow up!
2088 for arg in 2, 2L, 2j, 2e0, [2], "2", u"2", (2,), {2:2}, type, self.test_dir:
2089 dir(arg)
2090
2091 # Try classic classes.
2092 class C:
2093 Cdata = 1
2094 def Cmethod(self): pass
2095
2096 cstuff = ['Cdata', 'Cmethod', '__doc__', '__module__']
2097 self.assertEqual(dir(C), cstuff)
2098 self.assert_('im_self' in dir(C.Cmethod))
2099
2100 c = C() # c.__doc__ is an odd thing to see here; ditto c.__module__.
2101 self.assertEqual(dir(c), cstuff)
2102
2103 c.cdata = 2
2104 c.cmethod = lambda self: 0
2105 self.assertEqual(dir(c), cstuff + ['cdata', 'cmethod'])
2106 self.assert_('im_self' in dir(c.Cmethod))
2107
2108 class A(C):
2109 Adata = 1
2110 def Amethod(self): pass
2111
2112 astuff = ['Adata', 'Amethod'] + cstuff
2113 self.assertEqual(dir(A), astuff)
2114 self.assert_('im_self' in dir(A.Amethod))
2115 a = A()
2116 self.assertEqual(dir(a), astuff)
2117 self.assert_('im_self' in dir(a.Amethod))
2118 a.adata = 42
2119 a.amethod = lambda self: 3
2120 self.assertEqual(dir(a), astuff + ['adata', 'amethod'])
2121
2122 # The same, but with new-style classes. Since these have object as a
2123 # base class, a lot more gets sucked in.
2124 def interesting(strings):
2125 return [s for s in strings if not s.startswith('_')]
2126
2127 class C(object):
2128 Cdata = 1
2129 def Cmethod(self): pass
2130
2131 cstuff = ['Cdata', 'Cmethod']
2132 self.assertEqual(interesting(dir(C)), cstuff)
2133
2134 c = C()
2135 self.assertEqual(interesting(dir(c)), cstuff)
2136 self.assert_('im_self' in dir(C.Cmethod))
2137
2138 c.cdata = 2
2139 c.cmethod = lambda self: 0
2140 self.assertEqual(interesting(dir(c)), cstuff + ['cdata', 'cmethod'])
2141 self.assert_('im_self' in dir(c.Cmethod))
2142
2143 class A(C):
2144 Adata = 1
2145 def Amethod(self): pass
2146
2147 astuff = ['Adata', 'Amethod'] + cstuff
2148 self.assertEqual(interesting(dir(A)), astuff)
2149 self.assert_('im_self' in dir(A.Amethod))
2150 a = A()
2151 self.assertEqual(interesting(dir(a)), astuff)
2152 a.adata = 42
2153 a.amethod = lambda self: 3
2154 self.assertEqual(interesting(dir(a)), astuff + ['adata', 'amethod'])
2155 self.assert_('im_self' in dir(a.Amethod))
2156
2157 # Try a module subclass.
2158 import sys
2159 class M(type(sys)):
2160 pass
2161 minstance = M("m")
2162 minstance.b = 2
2163 minstance.a = 1
2164 names = [x for x in dir(minstance) if x not in ["__name__", "__doc__"]]
2165 self.assertEqual(names, ['a', 'b'])
2166
2167 class M2(M):
2168 def getdict(self):
2169 return "Not a dict!"
2170 __dict__ = property(getdict)
2171
2172 m2instance = M2("m2")
2173 m2instance.b = 2
2174 m2instance.a = 1
2175 self.assertEqual(m2instance.__dict__, "Not a dict!")
2176 try:
2177 dir(m2instance)
2178 except TypeError:
2179 pass
2180
2181 # Two essentially featureless objects, just inheriting stuff from
2182 # object.
2183 self.assertEqual(dir(None), dir(Ellipsis))
2184
2185 # Nasty test case for proxied objects
2186 class Wrapper(object):
2187 def __init__(self, obj):
2188 self.__obj = obj
2189 def __repr__(self):
2190 return "Wrapper(%s)" % repr(self.__obj)
2191 def __getitem__(self, key):
2192 return Wrapper(self.__obj[key])
2193 def __len__(self):
2194 return len(self.__obj)
2195 def __getattr__(self, name):
2196 return Wrapper(getattr(self.__obj, name))
2197
2198 class C(object):
2199 def __getclass(self):
2200 return Wrapper(type(self))
2201 __class__ = property(__getclass)
2202
2203 dir(C()) # This used to segfault
2204
2205 def test_supers(self):
2206 # Testing super...
2207
2208 class A(object):
2209 def meth(self, a):
2210 return "A(%r)" % a
2211
2212 self.assertEqual(A().meth(1), "A(1)")
2213
2214 class B(A):
2215 def __init__(self):
2216 self.__super = super(B, self)
2217 def meth(self, a):
2218 return "B(%r)" % a + self.__super.meth(a)
2219
2220 self.assertEqual(B().meth(2), "B(2)A(2)")
2221
2222 class C(A):
2223 def meth(self, a):
2224 return "C(%r)" % a + self.__super.meth(a)
2225 C._C__super = super(C)
2226
2227 self.assertEqual(C().meth(3), "C(3)A(3)")
2228
2229 class D(C, B):
2230 def meth(self, a):
2231 return "D(%r)" % a + super(D, self).meth(a)
2232
2233 self.assertEqual(D().meth(4), "D(4)C(4)B(4)A(4)")
2234
2235 # Test for subclassing super
2236
2237 class mysuper(super):
2238 def __init__(self, *args):
2239 return super(mysuper, self).__init__(*args)
2240
2241 class E(D):
2242 def meth(self, a):
2243 return "E(%r)" % a + mysuper(E, self).meth(a)
2244
2245 self.assertEqual(E().meth(5), "E(5)D(5)C(5)B(5)A(5)")
2246
2247 class F(E):
2248 def meth(self, a):
2249 s = self.__super # == mysuper(F, self)
2250 return "F(%r)[%s]" % (a, s.__class__.__name__) + s.meth(a)
2251 F._F__super = mysuper(F)
2252
2253 self.assertEqual(F().meth(6), "F(6)[mysuper]E(6)D(6)C(6)B(6)A(6)")
2254
2255 # Make sure certain errors are raised
2256
2257 try:
2258 super(D, 42)
2259 except TypeError:
2260 pass
2261 else:
2262 self.fail("shouldn't allow super(D, 42)")
2263
2264 try:
2265 super(D, C())
2266 except TypeError:
2267 pass
2268 else:
2269 self.fail("shouldn't allow super(D, C())")
2270
2271 try:
2272 super(D).__get__(12)
2273 except TypeError:
2274 pass
2275 else:
2276 self.fail("shouldn't allow super(D).__get__(12)")
2277
2278 try:
2279 super(D).__get__(C())
2280 except TypeError:
2281 pass
2282 else:
2283 self.fail("shouldn't allow super(D).__get__(C())")
2284
2285 # Make sure data descriptors can be overridden and accessed via super
2286 # (new feature in Python 2.3)
2287
2288 class DDbase(object):
2289 def getx(self): return 42
2290 x = property(getx)
2291
2292 class DDsub(DDbase):
2293 def getx(self): return "hello"
2294 x = property(getx)
2295
2296 dd = DDsub()
2297 self.assertEqual(dd.x, "hello")
2298 self.assertEqual(super(DDsub, dd).x, 42)
2299
2300 # Ensure that super() lookup of descriptor from classmethod
2301 # works (SF ID# 743627)
2302
2303 class Base(object):
2304 aProp = property(lambda self: "foo")
2305
2306 class Sub(Base):
2307 @classmethod
2308 def test(klass):
2309 return super(Sub,klass).aProp
2310
2311 self.assertEqual(Sub.test(), Base.aProp)
2312
2313 # Verify that super() doesn't allow keyword args
2314 try:
2315 super(Base, kw=1)
2316 except TypeError:
2317 pass
2318 else:
2319 self.assertEqual("super shouldn't accept keyword args")
2320
2321 def test_basic_inheritance(self):
2322 # Testing inheritance from basic types...
2323
2324 class hexint(int):
2325 def __repr__(self):
2326 return hex(self)
2327 def __add__(self, other):
2328 return hexint(int.__add__(self, other))
2329 # (Note that overriding __radd__ doesn't work,
2330 # because the int type gets first dibs.)
2331 self.assertEqual(repr(hexint(7) + 9), "0x10")
2332 self.assertEqual(repr(hexint(1000) + 7), "0x3ef")
2333 a = hexint(12345)
2334 self.assertEqual(a, 12345)
2335 self.assertEqual(int(a), 12345)
2336 self.assert_(int(a).__class__ is int)
2337 self.assertEqual(hash(a), hash(12345))
2338 self.assert_((+a).__class__ is int)
2339 self.assert_((a >> 0).__class__ is int)
2340 self.assert_((a << 0).__class__ is int)
2341 self.assert_((hexint(0) << 12).__class__ is int)
2342 self.assert_((hexint(0) >> 12).__class__ is int)
2343
2344 class octlong(long):
2345 __slots__ = []
2346 def __str__(self):
2347 s = oct(self)
2348 if s[-1] == 'L':
2349 s = s[:-1]
2350 return s
2351 def __add__(self, other):
2352 return self.__class__(super(octlong, self).__add__(other))
2353 __radd__ = __add__
2354 self.assertEqual(str(octlong(3) + 5), "010")
2355 # (Note that overriding __radd__ here only seems to work
2356 # because the example uses a short int left argument.)
2357 self.assertEqual(str(5 + octlong(3000)), "05675")
2358 a = octlong(12345)
2359 self.assertEqual(a, 12345L)
2360 self.assertEqual(long(a), 12345L)
2361 self.assertEqual(hash(a), hash(12345L))
2362 self.assert_(long(a).__class__ is long)
2363 self.assert_((+a).__class__ is long)
2364 self.assert_((-a).__class__ is long)
2365 self.assert_((-octlong(0)).__class__ is long)
2366 self.assert_((a >> 0).__class__ is long)
2367 self.assert_((a << 0).__class__ is long)
2368 self.assert_((a - 0).__class__ is long)
2369 self.assert_((a * 1).__class__ is long)
2370 self.assert_((a ** 1).__class__ is long)
2371 self.assert_((a // 1).__class__ is long)
2372 self.assert_((1 * a).__class__ is long)
2373 self.assert_((a | 0).__class__ is long)
2374 self.assert_((a ^ 0).__class__ is long)
2375 self.assert_((a & -1L).__class__ is long)
2376 self.assert_((octlong(0) << 12).__class__ is long)
2377 self.assert_((octlong(0) >> 12).__class__ is long)
2378 self.assert_(abs(octlong(0)).__class__ is long)
2379
2380 # Because octlong overrides __add__, we can't check the absence of +0
2381 # optimizations using octlong.
2382 class longclone(long):
2383 pass
2384 a = longclone(1)
2385 self.assert_((a + 0).__class__ is long)
2386 self.assert_((0 + a).__class__ is long)
2387
2388 # Check that negative clones don't segfault
2389 a = longclone(-1)
2390 self.assertEqual(a.__dict__, {})
2391 self.assertEqual(long(a), -1) # self.assert_ PyNumber_Long() copies the sign bit
2392
2393 class precfloat(float):
2394 __slots__ = ['prec']
2395 def __init__(self, value=0.0, prec=12):
2396 self.prec = int(prec)
2397 def __repr__(self):
2398 return "%.*g" % (self.prec, self)
2399 self.assertEqual(repr(precfloat(1.1)), "1.1")
2400 a = precfloat(12345)
2401 self.assertEqual(a, 12345.0)
2402 self.assertEqual(float(a), 12345.0)
2403 self.assert_(float(a).__class__ is float)
2404 self.assertEqual(hash(a), hash(12345.0))
2405 self.assert_((+a).__class__ is float)
2406
2407 class madcomplex(complex):
2408 def __repr__(self):
2409 return "%.17gj%+.17g" % (self.imag, self.real)
2410 a = madcomplex(-3, 4)
2411 self.assertEqual(repr(a), "4j-3")
2412 base = complex(-3, 4)
2413 self.assertEqual(base.__class__, complex)
2414 self.assertEqual(a, base)
2415 self.assertEqual(complex(a), base)
2416 self.assertEqual(complex(a).__class__, complex)
2417 a = madcomplex(a) # just trying another form of the constructor
2418 self.assertEqual(repr(a), "4j-3")
2419 self.assertEqual(a, base)
2420 self.assertEqual(complex(a), base)
2421 self.assertEqual(complex(a).__class__, complex)
2422 self.assertEqual(hash(a), hash(base))
2423 self.assertEqual((+a).__class__, complex)
2424 self.assertEqual((a + 0).__class__, complex)
2425 self.assertEqual(a + 0, base)
2426 self.assertEqual((a - 0).__class__, complex)
2427 self.assertEqual(a - 0, base)
2428 self.assertEqual((a * 1).__class__, complex)
2429 self.assertEqual(a * 1, base)
2430 self.assertEqual((a / 1).__class__, complex)
2431 self.assertEqual(a / 1, base)
2432
2433 class madtuple(tuple):
2434 _rev = None
2435 def rev(self):
2436 if self._rev is not None:
2437 return self._rev
2438 L = list(self)
2439 L.reverse()
2440 self._rev = self.__class__(L)
2441 return self._rev
2442 a = madtuple((1,2,3,4,5,6,7,8,9,0))
2443 self.assertEqual(a, (1,2,3,4,5,6,7,8,9,0))
2444 self.assertEqual(a.rev(), madtuple((0,9,8,7,6,5,4,3,2,1)))
2445 self.assertEqual(a.rev().rev(), madtuple((1,2,3,4,5,6,7,8,9,0)))
2446 for i in range(512):
2447 t = madtuple(range(i))
2448 u = t.rev()
2449 v = u.rev()
2450 self.assertEqual(v, t)
2451 a = madtuple((1,2,3,4,5))
2452 self.assertEqual(tuple(a), (1,2,3,4,5))
2453 self.assert_(tuple(a).__class__ is tuple)
2454 self.assertEqual(hash(a), hash((1,2,3,4,5)))
2455 self.assert_(a[:].__class__ is tuple)
2456 self.assert_((a * 1).__class__ is tuple)
2457 self.assert_((a * 0).__class__ is tuple)
2458 self.assert_((a + ()).__class__ is tuple)
2459 a = madtuple(())
2460 self.assertEqual(tuple(a), ())
2461 self.assert_(tuple(a).__class__ is tuple)
2462 self.assert_((a + a).__class__ is tuple)
2463 self.assert_((a * 0).__class__ is tuple)
2464 self.assert_((a * 1).__class__ is tuple)
2465 self.assert_((a * 2).__class__ is tuple)
2466 self.assert_(a[:].__class__ is tuple)
2467
2468 class madstring(str):
2469 _rev = None
2470 def rev(self):
2471 if self._rev is not None:
2472 return self._rev
2473 L = list(self)
2474 L.reverse()
2475 self._rev = self.__class__("".join(L))
2476 return self._rev
2477 s = madstring("abcdefghijklmnopqrstuvwxyz")
2478 self.assertEqual(s, "abcdefghijklmnopqrstuvwxyz")
2479 self.assertEqual(s.rev(), madstring("zyxwvutsrqponmlkjihgfedcba"))
2480 self.assertEqual(s.rev().rev(), madstring("abcdefghijklmnopqrstuvwxyz"))
2481 for i in range(256):
2482 s = madstring("".join(map(chr, range(i))))
2483 t = s.rev()
2484 u = t.rev()
2485 self.assertEqual(u, s)
2486 s = madstring("12345")
2487 self.assertEqual(str(s), "12345")
2488 self.assert_(str(s).__class__ is str)
2489
2490 base = "\x00" * 5
2491 s = madstring(base)
2492 self.assertEqual(s, base)
2493 self.assertEqual(str(s), base)
2494 self.assert_(str(s).__class__ is str)
2495 self.assertEqual(hash(s), hash(base))
2496 self.assertEqual({s: 1}[base], 1)
2497 self.assertEqual({base: 1}[s], 1)
2498 self.assert_((s + "").__class__ is str)
2499 self.assertEqual(s + "", base)
2500 self.assert_(("" + s).__class__ is str)
2501 self.assertEqual("" + s, base)
2502 self.assert_((s * 0).__class__ is str)
2503 self.assertEqual(s * 0, "")
2504 self.assert_((s * 1).__class__ is str)
2505 self.assertEqual(s * 1, base)
2506 self.assert_((s * 2).__class__ is str)
2507 self.assertEqual(s * 2, base + base)
2508 self.assert_(s[:].__class__ is str)
2509 self.assertEqual(s[:], base)
2510 self.assert_(s[0:0].__class__ is str)
2511 self.assertEqual(s[0:0], "")
2512 self.assert_(s.strip().__class__ is str)
2513 self.assertEqual(s.strip(), base)
2514 self.assert_(s.lstrip().__class__ is str)
2515 self.assertEqual(s.lstrip(), base)
2516 self.assert_(s.rstrip().__class__ is str)
2517 self.assertEqual(s.rstrip(), base)
2518 identitytab = ''.join([chr(i) for i in range(256)])
2519 self.assert_(s.translate(identitytab).__class__ is str)
2520 self.assertEqual(s.translate(identitytab), base)
2521 self.assert_(s.translate(identitytab, "x").__class__ is str)
2522 self.assertEqual(s.translate(identitytab, "x"), base)
2523 self.assertEqual(s.translate(identitytab, "\x00"), "")
2524 self.assert_(s.replace("x", "x").__class__ is str)
2525 self.assertEqual(s.replace("x", "x"), base)
2526 self.assert_(s.ljust(len(s)).__class__ is str)
2527 self.assertEqual(s.ljust(len(s)), base)
2528 self.assert_(s.rjust(len(s)).__class__ is str)
2529 self.assertEqual(s.rjust(len(s)), base)
2530 self.assert_(s.center(len(s)).__class__ is str)
2531 self.assertEqual(s.center(len(s)), base)
2532 self.assert_(s.lower().__class__ is str)
2533 self.assertEqual(s.lower(), base)
2534
2535 class madunicode(unicode):
2536 _rev = None
2537 def rev(self):
2538 if self._rev is not None:
2539 return self._rev
2540 L = list(self)
2541 L.reverse()
2542 self._rev = self.__class__(u"".join(L))
2543 return self._rev
2544 u = madunicode("ABCDEF")
2545 self.assertEqual(u, u"ABCDEF")
2546 self.assertEqual(u.rev(), madunicode(u"FEDCBA"))
2547 self.assertEqual(u.rev().rev(), madunicode(u"ABCDEF"))
2548 base = u"12345"
2549 u = madunicode(base)
2550 self.assertEqual(unicode(u), base)
2551 self.assert_(unicode(u).__class__ is unicode)
2552 self.assertEqual(hash(u), hash(base))
2553 self.assertEqual({u: 1}[base], 1)
2554 self.assertEqual({base: 1}[u], 1)
2555 self.assert_(u.strip().__class__ is unicode)
2556 self.assertEqual(u.strip(), base)
2557 self.assert_(u.lstrip().__class__ is unicode)
2558 self.assertEqual(u.lstrip(), base)
2559 self.assert_(u.rstrip().__class__ is unicode)
2560 self.assertEqual(u.rstrip(), base)
2561 self.assert_(u.replace(u"x", u"x").__class__ is unicode)
2562 self.assertEqual(u.replace(u"x", u"x"), base)
2563 self.assert_(u.replace(u"xy", u"xy").__class__ is unicode)
2564 self.assertEqual(u.replace(u"xy", u"xy"), base)
2565 self.assert_(u.center(len(u)).__class__ is unicode)
2566 self.assertEqual(u.center(len(u)), base)
2567 self.assert_(u.ljust(len(u)).__class__ is unicode)
2568 self.assertEqual(u.ljust(len(u)), base)
2569 self.assert_(u.rjust(len(u)).__class__ is unicode)
2570 self.assertEqual(u.rjust(len(u)), base)
2571 self.assert_(u.lower().__class__ is unicode)
2572 self.assertEqual(u.lower(), base)
2573 self.assert_(u.upper().__class__ is unicode)
2574 self.assertEqual(u.upper(), base)
2575 self.assert_(u.capitalize().__class__ is unicode)
2576 self.assertEqual(u.capitalize(), base)
2577 self.assert_(u.title().__class__ is unicode)
2578 self.assertEqual(u.title(), base)
2579 self.assert_((u + u"").__class__ is unicode)
2580 self.assertEqual(u + u"", base)
2581 self.assert_((u"" + u).__class__ is unicode)
2582 self.assertEqual(u"" + u, base)
2583 self.assert_((u * 0).__class__ is unicode)
2584 self.assertEqual(u * 0, u"")
2585 self.assert_((u * 1).__class__ is unicode)
2586 self.assertEqual(u * 1, base)
2587 self.assert_((u * 2).__class__ is unicode)
2588 self.assertEqual(u * 2, base + base)
2589 self.assert_(u[:].__class__ is unicode)
2590 self.assertEqual(u[:], base)
2591 self.assert_(u[0:0].__class__ is unicode)
2592 self.assertEqual(u[0:0], u"")
2593
2594 class sublist(list):
2595 pass
2596 a = sublist(range(5))
2597 self.assertEqual(a, range(5))
2598 a.append("hello")
2599 self.assertEqual(a, range(5) + ["hello"])
2600 a[5] = 5
2601 self.assertEqual(a, range(6))
2602 a.extend(range(6, 20))
2603 self.assertEqual(a, range(20))
2604 a[-5:] = []
2605 self.assertEqual(a, range(15))
2606 del a[10:15]
2607 self.assertEqual(len(a), 10)
2608 self.assertEqual(a, range(10))
2609 self.assertEqual(list(a), range(10))
2610 self.assertEqual(a[0], 0)
2611 self.assertEqual(a[9], 9)
2612 self.assertEqual(a[-10], 0)
2613 self.assertEqual(a[-1], 9)
2614 self.assertEqual(a[:5], range(5))
2615
2616 class CountedInput(file):
2617 """Counts lines read by self.readline().
2618
2619 self.lineno is the 0-based ordinal of the last line read, up to
2620 a maximum of one greater than the number of lines in the file.
2621
2622 self.ateof is true if and only if the final "" line has been read,
2623 at which point self.lineno stops incrementing, and further calls
2624 to readline() continue to return "".
2625 """
2626
2627 lineno = 0
2628 ateof = 0
2629 def readline(self):
2630 if self.ateof:
2631 return ""
2632 s = file.readline(self)
2633 # Next line works too.
2634 # s = super(CountedInput, self).readline()
2635 self.lineno += 1
2636 if s == "":
2637 self.ateof = 1
2638 return s
2639
2640 f = file(name=test_support.TESTFN, mode='w')
2641 lines = ['a\n', 'b\n', 'c\n']
2642 try:
2643 f.writelines(lines)
2644 f.close()
2645 f = CountedInput(test_support.TESTFN)
2646 for (i, expected) in zip(range(1, 5) + [4], lines + 2 * [""]):
2647 got = f.readline()
2648 self.assertEqual(expected, got)
2649 self.assertEqual(f.lineno, i)
2650 self.assertEqual(f.ateof, (i > len(lines)))
2651 f.close()
2652 finally:
2653 try:
2654 f.close()
2655 except:
2656 pass
2657 test_support.unlink(test_support.TESTFN)
2658
2659 def test_keywords(self):
2660 # Testing keyword args to basic type constructors ...
2661 self.assertEqual(int(x=1), 1)
2662 self.assertEqual(float(x=2), 2.0)
2663 self.assertEqual(long(x=3), 3L)
2664 self.assertEqual(complex(imag=42, real=666), complex(666, 42))
2665 self.assertEqual(str(object=500), '500')
2666 self.assertEqual(unicode(string='abc', errors='strict'), u'abc')
2667 self.assertEqual(tuple(sequence=range(3)), (0, 1, 2))
2668 self.assertEqual(list(sequence=(0, 1, 2)), range(3))
2669 # note: as of Python 2.3, dict() no longer has an "items" keyword arg
2670
2671 for constructor in (int, float, long, complex, str, unicode,
2672 tuple, list, file):
2673 try:
2674 constructor(bogus_keyword_arg=1)
2675 except TypeError:
2676 pass
2677 else:
2678 self.fail("expected TypeError from bogus keyword argument to %r"
2679 % constructor)
2680
2681 def test_str_subclass_as_dict_key(self):
2682 # Testing a str subclass used as dict key ..
2683
2684 class cistr(str):
2685 """Sublcass of str that computes __eq__ case-insensitively.
2686
2687 Also computes a hash code of the string in canonical form.
2688 """
2689
2690 def __init__(self, value):
2691 self.canonical = value.lower()
2692 self.hashcode = hash(self.canonical)
2693
2694 def __eq__(self, other):
2695 if not isinstance(other, cistr):
2696 other = cistr(other)
2697 return self.canonical == other.canonical
2698
2699 def __hash__(self):
2700 return self.hashcode
2701
2702 self.assertEqual(cistr('ABC'), 'abc')
2703 self.assertEqual('aBc', cistr('ABC'))
2704 self.assertEqual(str(cistr('ABC')), 'ABC')
2705
2706 d = {cistr('one'): 1, cistr('two'): 2, cistr('tHree'): 3}
2707 self.assertEqual(d[cistr('one')], 1)
2708 self.assertEqual(d[cistr('tWo')], 2)
2709 self.assertEqual(d[cistr('THrEE')], 3)
2710 self.assert_(cistr('ONe') in d)
2711 self.assertEqual(d.get(cistr('thrEE')), 3)
2712
2713 def test_classic_comparisons(self):
2714 # Testing classic comparisons...
2715 class classic:
2716 pass
2717
2718 for base in (classic, int, object):
2719 class C(base):
2720 def __init__(self, value):
2721 self.value = int(value)
2722 def __cmp__(self, other):
2723 if isinstance(other, C):
2724 return cmp(self.value, other.value)
2725 if isinstance(other, int) or isinstance(other, long):
2726 return cmp(self.value, other)
2727 return NotImplemented
Nick Coghlan48361f52008-08-11 15:45:58 +00002728 __hash__ = None # Silence Py3k warning
Georg Brandl48545522008-02-02 10:12:36 +00002729
2730 c1 = C(1)
2731 c2 = C(2)
2732 c3 = C(3)
2733 self.assertEqual(c1, 1)
2734 c = {1: c1, 2: c2, 3: c3}
2735 for x in 1, 2, 3:
2736 for y in 1, 2, 3:
2737 self.assert_(cmp(c[x], c[y]) == cmp(x, y), "x=%d, y=%d" % (x, y))
2738 for op in "<", "<=", "==", "!=", ">", ">=":
2739 self.assert_(eval("c[x] %s c[y]" % op) == eval("x %s y" % op),
2740 "x=%d, y=%d" % (x, y))
2741 self.assert_(cmp(c[x], y) == cmp(x, y), "x=%d, y=%d" % (x, y))
2742 self.assert_(cmp(x, c[y]) == cmp(x, y), "x=%d, y=%d" % (x, y))
2743
2744 def test_rich_comparisons(self):
2745 # Testing rich comparisons...
2746 class Z(complex):
2747 pass
2748 z = Z(1)
2749 self.assertEqual(z, 1+0j)
2750 self.assertEqual(1+0j, z)
2751 class ZZ(complex):
2752 def __eq__(self, other):
2753 try:
2754 return abs(self - other) <= 1e-6
2755 except:
2756 return NotImplemented
Nick Coghlan48361f52008-08-11 15:45:58 +00002757 __hash__ = None # Silence Py3k warning
Georg Brandl48545522008-02-02 10:12:36 +00002758 zz = ZZ(1.0000003)
2759 self.assertEqual(zz, 1+0j)
2760 self.assertEqual(1+0j, zz)
2761
2762 class classic:
2763 pass
2764 for base in (classic, int, object, list):
2765 class C(base):
2766 def __init__(self, value):
2767 self.value = int(value)
2768 def __cmp__(self_, other):
2769 self.fail("shouldn't call __cmp__")
Nick Coghlan48361f52008-08-11 15:45:58 +00002770 __hash__ = None # Silence Py3k warning
Georg Brandl48545522008-02-02 10:12:36 +00002771 def __eq__(self, other):
2772 if isinstance(other, C):
2773 return self.value == other.value
2774 if isinstance(other, int) or isinstance(other, long):
2775 return self.value == other
2776 return NotImplemented
2777 def __ne__(self, other):
2778 if isinstance(other, C):
2779 return self.value != other.value
2780 if isinstance(other, int) or isinstance(other, long):
2781 return self.value != other
2782 return NotImplemented
2783 def __lt__(self, other):
2784 if isinstance(other, C):
2785 return self.value < other.value
2786 if isinstance(other, int) or isinstance(other, long):
2787 return self.value < other
2788 return NotImplemented
2789 def __le__(self, other):
2790 if isinstance(other, C):
2791 return self.value <= other.value
2792 if isinstance(other, int) or isinstance(other, long):
2793 return self.value <= other
2794 return NotImplemented
2795 def __gt__(self, other):
2796 if isinstance(other, C):
2797 return self.value > other.value
2798 if isinstance(other, int) or isinstance(other, long):
2799 return self.value > other
2800 return NotImplemented
2801 def __ge__(self, other):
2802 if isinstance(other, C):
2803 return self.value >= other.value
2804 if isinstance(other, int) or isinstance(other, long):
2805 return self.value >= other
2806 return NotImplemented
2807 c1 = C(1)
2808 c2 = C(2)
2809 c3 = C(3)
2810 self.assertEqual(c1, 1)
2811 c = {1: c1, 2: c2, 3: c3}
2812 for x in 1, 2, 3:
2813 for y in 1, 2, 3:
2814 for op in "<", "<=", "==", "!=", ">", ">=":
2815 self.assert_(eval("c[x] %s c[y]" % op) == eval("x %s y" % op),
2816 "x=%d, y=%d" % (x, y))
2817 self.assert_(eval("c[x] %s y" % op) == eval("x %s y" % op),
2818 "x=%d, y=%d" % (x, y))
2819 self.assert_(eval("x %s c[y]" % op) == eval("x %s y" % op),
2820 "x=%d, y=%d" % (x, y))
2821
2822 def test_coercions(self):
2823 # Testing coercions...
2824 class I(int): pass
2825 coerce(I(0), 0)
2826 coerce(0, I(0))
2827 class L(long): pass
2828 coerce(L(0), 0)
2829 coerce(L(0), 0L)
2830 coerce(0, L(0))
2831 coerce(0L, L(0))
2832 class F(float): pass
2833 coerce(F(0), 0)
2834 coerce(F(0), 0L)
2835 coerce(F(0), 0.)
2836 coerce(0, F(0))
2837 coerce(0L, F(0))
2838 coerce(0., F(0))
2839 class C(complex): pass
2840 coerce(C(0), 0)
2841 coerce(C(0), 0L)
2842 coerce(C(0), 0.)
2843 coerce(C(0), 0j)
2844 coerce(0, C(0))
2845 coerce(0L, C(0))
2846 coerce(0., C(0))
2847 coerce(0j, C(0))
2848
2849 def test_descrdoc(self):
2850 # Testing descriptor doc strings...
2851 def check(descr, what):
2852 self.assertEqual(descr.__doc__, what)
2853 check(file.closed, "True if the file is closed") # getset descriptor
2854 check(file.name, "file name") # member descriptor
2855
2856 def test_doc_descriptor(self):
2857 # Testing __doc__ descriptor...
2858 # SF bug 542984
2859 class DocDescr(object):
2860 def __get__(self, object, otype):
2861 if object:
2862 object = object.__class__.__name__ + ' instance'
2863 if otype:
2864 otype = otype.__name__
2865 return 'object=%s; type=%s' % (object, otype)
2866 class OldClass:
2867 __doc__ = DocDescr()
2868 class NewClass(object):
2869 __doc__ = DocDescr()
2870 self.assertEqual(OldClass.__doc__, 'object=None; type=OldClass')
2871 self.assertEqual(OldClass().__doc__, 'object=OldClass instance; type=OldClass')
2872 self.assertEqual(NewClass.__doc__, 'object=None; type=NewClass')
2873 self.assertEqual(NewClass().__doc__, 'object=NewClass instance; type=NewClass')
2874
2875 def test_set_class(self):
2876 # Testing __class__ assignment...
2877 class C(object): pass
2878 class D(object): pass
2879 class E(object): pass
2880 class F(D, E): pass
2881 for cls in C, D, E, F:
2882 for cls2 in C, D, E, F:
2883 x = cls()
2884 x.__class__ = cls2
2885 self.assert_(x.__class__ is cls2)
2886 x.__class__ = cls
2887 self.assert_(x.__class__ is cls)
2888 def cant(x, C):
2889 try:
2890 x.__class__ = C
2891 except TypeError:
2892 pass
2893 else:
2894 self.fail("shouldn't allow %r.__class__ = %r" % (x, C))
2895 try:
2896 delattr(x, "__class__")
2897 except TypeError:
2898 pass
2899 else:
2900 self.fail("shouldn't allow del %r.__class__" % x)
2901 cant(C(), list)
2902 cant(list(), C)
2903 cant(C(), 1)
2904 cant(C(), object)
2905 cant(object(), list)
2906 cant(list(), object)
2907 class Int(int): __slots__ = []
2908 cant(2, Int)
2909 cant(Int(), int)
2910 cant(True, int)
2911 cant(2, bool)
2912 o = object()
2913 cant(o, type(1))
2914 cant(o, type(None))
2915 del o
2916 class G(object):
2917 __slots__ = ["a", "b"]
2918 class H(object):
2919 __slots__ = ["b", "a"]
2920 try:
2921 unicode
2922 except NameError:
2923 class I(object):
2924 __slots__ = ["a", "b"]
2925 else:
2926 class I(object):
2927 __slots__ = [unicode("a"), unicode("b")]
2928 class J(object):
2929 __slots__ = ["c", "b"]
2930 class K(object):
2931 __slots__ = ["a", "b", "d"]
2932 class L(H):
2933 __slots__ = ["e"]
2934 class M(I):
2935 __slots__ = ["e"]
2936 class N(J):
2937 __slots__ = ["__weakref__"]
2938 class P(J):
2939 __slots__ = ["__dict__"]
2940 class Q(J):
2941 pass
2942 class R(J):
2943 __slots__ = ["__dict__", "__weakref__"]
2944
2945 for cls, cls2 in ((G, H), (G, I), (I, H), (Q, R), (R, Q)):
2946 x = cls()
2947 x.a = 1
2948 x.__class__ = cls2
2949 self.assert_(x.__class__ is cls2,
2950 "assigning %r as __class__ for %r silently failed" % (cls2, x))
2951 self.assertEqual(x.a, 1)
2952 x.__class__ = cls
2953 self.assert_(x.__class__ is cls,
2954 "assigning %r as __class__ for %r silently failed" % (cls, x))
2955 self.assertEqual(x.a, 1)
2956 for cls in G, J, K, L, M, N, P, R, list, Int:
2957 for cls2 in G, J, K, L, M, N, P, R, list, Int:
2958 if cls is cls2:
2959 continue
2960 cant(cls(), cls2)
2961
Benjamin Petersonaf75a5f2009-04-25 00:44:44 +00002962 # Issue5283: when __class__ changes in __del__, the wrong
2963 # type gets DECREF'd.
2964 class O(object):
2965 pass
2966 class A(object):
2967 def __del__(self):
2968 self.__class__ = O
2969 l = [A() for x in range(100)]
2970 del l
2971
Georg Brandl48545522008-02-02 10:12:36 +00002972 def test_set_dict(self):
2973 # Testing __dict__ assignment...
2974 class C(object): pass
2975 a = C()
2976 a.__dict__ = {'b': 1}
2977 self.assertEqual(a.b, 1)
2978 def cant(x, dict):
2979 try:
2980 x.__dict__ = dict
2981 except (AttributeError, TypeError):
2982 pass
2983 else:
2984 self.fail("shouldn't allow %r.__dict__ = %r" % (x, dict))
2985 cant(a, None)
2986 cant(a, [])
2987 cant(a, 1)
2988 del a.__dict__ # Deleting __dict__ is allowed
2989
2990 class Base(object):
2991 pass
2992 def verify_dict_readonly(x):
2993 """
2994 x has to be an instance of a class inheriting from Base.
2995 """
2996 cant(x, {})
2997 try:
2998 del x.__dict__
2999 except (AttributeError, TypeError):
3000 pass
3001 else:
3002 self.fail("shouldn't allow del %r.__dict__" % x)
3003 dict_descr = Base.__dict__["__dict__"]
3004 try:
3005 dict_descr.__set__(x, {})
3006 except (AttributeError, TypeError):
3007 pass
3008 else:
3009 self.fail("dict_descr allowed access to %r's dict" % x)
3010
3011 # Classes don't allow __dict__ assignment and have readonly dicts
3012 class Meta1(type, Base):
3013 pass
3014 class Meta2(Base, type):
3015 pass
3016 class D(object):
3017 __metaclass__ = Meta1
3018 class E(object):
3019 __metaclass__ = Meta2
3020 for cls in C, D, E:
3021 verify_dict_readonly(cls)
3022 class_dict = cls.__dict__
3023 try:
3024 class_dict["spam"] = "eggs"
3025 except TypeError:
3026 pass
3027 else:
3028 self.fail("%r's __dict__ can be modified" % cls)
3029
3030 # Modules also disallow __dict__ assignment
3031 class Module1(types.ModuleType, Base):
3032 pass
3033 class Module2(Base, types.ModuleType):
3034 pass
3035 for ModuleType in Module1, Module2:
3036 mod = ModuleType("spam")
3037 verify_dict_readonly(mod)
3038 mod.__dict__["spam"] = "eggs"
3039
3040 # Exception's __dict__ can be replaced, but not deleted
3041 class Exception1(Exception, Base):
3042 pass
3043 class Exception2(Base, Exception):
3044 pass
3045 for ExceptionType in Exception, Exception1, Exception2:
3046 e = ExceptionType()
3047 e.__dict__ = {"a": 1}
3048 self.assertEqual(e.a, 1)
3049 try:
3050 del e.__dict__
3051 except (TypeError, AttributeError):
3052 pass
3053 else:
3054 self.fail("%r's __dict__ can be deleted" % e)
3055
3056 def test_pickles(self):
3057 # Testing pickling and copying new-style classes and objects...
3058 import pickle, cPickle
3059
3060 def sorteditems(d):
3061 L = d.items()
3062 L.sort()
3063 return L
3064
3065 global C
3066 class C(object):
3067 def __init__(self, a, b):
3068 super(C, self).__init__()
3069 self.a = a
3070 self.b = b
3071 def __repr__(self):
3072 return "C(%r, %r)" % (self.a, self.b)
3073
3074 global C1
3075 class C1(list):
3076 def __new__(cls, a, b):
3077 return super(C1, cls).__new__(cls)
3078 def __getnewargs__(self):
3079 return (self.a, self.b)
3080 def __init__(self, a, b):
3081 self.a = a
3082 self.b = b
3083 def __repr__(self):
3084 return "C1(%r, %r)<%r>" % (self.a, self.b, list(self))
3085
3086 global C2
3087 class C2(int):
3088 def __new__(cls, a, b, val=0):
3089 return super(C2, cls).__new__(cls, val)
3090 def __getnewargs__(self):
3091 return (self.a, self.b, int(self))
3092 def __init__(self, a, b, val=0):
3093 self.a = a
3094 self.b = b
3095 def __repr__(self):
3096 return "C2(%r, %r)<%r>" % (self.a, self.b, int(self))
3097
3098 global C3
3099 class C3(object):
3100 def __init__(self, foo):
3101 self.foo = foo
3102 def __getstate__(self):
3103 return self.foo
3104 def __setstate__(self, foo):
3105 self.foo = foo
3106
3107 global C4classic, C4
3108 class C4classic: # classic
3109 pass
3110 class C4(C4classic, object): # mixed inheritance
3111 pass
3112
3113 for p in pickle, cPickle:
3114 for bin in 0, 1:
3115 for cls in C, C1, C2:
3116 s = p.dumps(cls, bin)
3117 cls2 = p.loads(s)
3118 self.assert_(cls2 is cls)
3119
3120 a = C1(1, 2); a.append(42); a.append(24)
3121 b = C2("hello", "world", 42)
3122 s = p.dumps((a, b), bin)
3123 x, y = p.loads(s)
3124 self.assertEqual(x.__class__, a.__class__)
3125 self.assertEqual(sorteditems(x.__dict__), sorteditems(a.__dict__))
3126 self.assertEqual(y.__class__, b.__class__)
3127 self.assertEqual(sorteditems(y.__dict__), sorteditems(b.__dict__))
3128 self.assertEqual(repr(x), repr(a))
3129 self.assertEqual(repr(y), repr(b))
3130 # Test for __getstate__ and __setstate__ on new style class
3131 u = C3(42)
3132 s = p.dumps(u, bin)
3133 v = p.loads(s)
3134 self.assertEqual(u.__class__, v.__class__)
3135 self.assertEqual(u.foo, v.foo)
3136 # Test for picklability of hybrid class
3137 u = C4()
3138 u.foo = 42
3139 s = p.dumps(u, bin)
3140 v = p.loads(s)
3141 self.assertEqual(u.__class__, v.__class__)
3142 self.assertEqual(u.foo, v.foo)
3143
3144 # Testing copy.deepcopy()
3145 import copy
3146 for cls in C, C1, C2:
3147 cls2 = copy.deepcopy(cls)
3148 self.assert_(cls2 is cls)
3149
3150 a = C1(1, 2); a.append(42); a.append(24)
3151 b = C2("hello", "world", 42)
3152 x, y = copy.deepcopy((a, b))
3153 self.assertEqual(x.__class__, a.__class__)
3154 self.assertEqual(sorteditems(x.__dict__), sorteditems(a.__dict__))
3155 self.assertEqual(y.__class__, b.__class__)
3156 self.assertEqual(sorteditems(y.__dict__), sorteditems(b.__dict__))
3157 self.assertEqual(repr(x), repr(a))
3158 self.assertEqual(repr(y), repr(b))
3159
3160 def test_pickle_slots(self):
3161 # Testing pickling of classes with __slots__ ...
3162 import pickle, cPickle
3163 # Pickling of classes with __slots__ but without __getstate__ should fail
3164 global B, C, D, E
3165 class B(object):
3166 pass
3167 for base in [object, B]:
3168 class C(base):
3169 __slots__ = ['a']
3170 class D(C):
3171 pass
3172 try:
3173 pickle.dumps(C())
3174 except TypeError:
3175 pass
3176 else:
3177 self.fail("should fail: pickle C instance - %s" % base)
3178 try:
3179 cPickle.dumps(C())
3180 except TypeError:
3181 pass
3182 else:
3183 self.fail("should fail: cPickle C instance - %s" % base)
3184 try:
3185 pickle.dumps(C())
3186 except TypeError:
3187 pass
3188 else:
3189 self.fail("should fail: pickle D instance - %s" % base)
3190 try:
3191 cPickle.dumps(D())
3192 except TypeError:
3193 pass
3194 else:
3195 self.fail("should fail: cPickle D instance - %s" % base)
3196 # Give C a nice generic __getstate__ and __setstate__
3197 class C(base):
3198 __slots__ = ['a']
3199 def __getstate__(self):
3200 try:
3201 d = self.__dict__.copy()
3202 except AttributeError:
3203 d = {}
3204 for cls in self.__class__.__mro__:
3205 for sn in cls.__dict__.get('__slots__', ()):
3206 try:
3207 d[sn] = getattr(self, sn)
3208 except AttributeError:
3209 pass
3210 return d
3211 def __setstate__(self, d):
3212 for k, v in d.items():
3213 setattr(self, k, v)
3214 class D(C):
3215 pass
3216 # Now it should work
3217 x = C()
3218 y = pickle.loads(pickle.dumps(x))
3219 self.assertEqual(hasattr(y, 'a'), 0)
3220 y = cPickle.loads(cPickle.dumps(x))
3221 self.assertEqual(hasattr(y, 'a'), 0)
3222 x.a = 42
3223 y = pickle.loads(pickle.dumps(x))
3224 self.assertEqual(y.a, 42)
3225 y = cPickle.loads(cPickle.dumps(x))
3226 self.assertEqual(y.a, 42)
3227 x = D()
3228 x.a = 42
3229 x.b = 100
3230 y = pickle.loads(pickle.dumps(x))
3231 self.assertEqual(y.a + y.b, 142)
3232 y = cPickle.loads(cPickle.dumps(x))
3233 self.assertEqual(y.a + y.b, 142)
3234 # A subclass that adds a slot should also work
3235 class E(C):
3236 __slots__ = ['b']
3237 x = E()
3238 x.a = 42
3239 x.b = "foo"
3240 y = pickle.loads(pickle.dumps(x))
3241 self.assertEqual(y.a, x.a)
3242 self.assertEqual(y.b, x.b)
3243 y = cPickle.loads(cPickle.dumps(x))
3244 self.assertEqual(y.a, x.a)
3245 self.assertEqual(y.b, x.b)
3246
3247 def test_binary_operator_override(self):
3248 # Testing overrides of binary operations...
3249 class I(int):
3250 def __repr__(self):
3251 return "I(%r)" % int(self)
3252 def __add__(self, other):
3253 return I(int(self) + int(other))
3254 __radd__ = __add__
3255 def __pow__(self, other, mod=None):
3256 if mod is None:
3257 return I(pow(int(self), int(other)))
3258 else:
3259 return I(pow(int(self), int(other), int(mod)))
3260 def __rpow__(self, other, mod=None):
3261 if mod is None:
3262 return I(pow(int(other), int(self), mod))
3263 else:
3264 return I(pow(int(other), int(self), int(mod)))
3265
3266 self.assertEqual(repr(I(1) + I(2)), "I(3)")
3267 self.assertEqual(repr(I(1) + 2), "I(3)")
3268 self.assertEqual(repr(1 + I(2)), "I(3)")
3269 self.assertEqual(repr(I(2) ** I(3)), "I(8)")
3270 self.assertEqual(repr(2 ** I(3)), "I(8)")
3271 self.assertEqual(repr(I(2) ** 3), "I(8)")
3272 self.assertEqual(repr(pow(I(2), I(3), I(5))), "I(3)")
3273 class S(str):
3274 def __eq__(self, other):
3275 return self.lower() == other.lower()
Nick Coghlan48361f52008-08-11 15:45:58 +00003276 __hash__ = None # Silence Py3k warning
Georg Brandl48545522008-02-02 10:12:36 +00003277
3278 def test_subclass_propagation(self):
3279 # Testing propagation of slot functions to subclasses...
3280 class A(object):
3281 pass
3282 class B(A):
3283 pass
3284 class C(A):
3285 pass
3286 class D(B, C):
3287 pass
3288 d = D()
3289 orig_hash = hash(d) # related to id(d) in platform-dependent ways
3290 A.__hash__ = lambda self: 42
3291 self.assertEqual(hash(d), 42)
3292 C.__hash__ = lambda self: 314
3293 self.assertEqual(hash(d), 314)
3294 B.__hash__ = lambda self: 144
3295 self.assertEqual(hash(d), 144)
3296 D.__hash__ = lambda self: 100
3297 self.assertEqual(hash(d), 100)
Nick Coghlan53663a62008-07-15 14:27:37 +00003298 D.__hash__ = None
3299 self.assertRaises(TypeError, hash, d)
Georg Brandl48545522008-02-02 10:12:36 +00003300 del D.__hash__
3301 self.assertEqual(hash(d), 144)
Nick Coghlan53663a62008-07-15 14:27:37 +00003302 B.__hash__ = None
3303 self.assertRaises(TypeError, hash, d)
Georg Brandl48545522008-02-02 10:12:36 +00003304 del B.__hash__
3305 self.assertEqual(hash(d), 314)
Nick Coghlan53663a62008-07-15 14:27:37 +00003306 C.__hash__ = None
3307 self.assertRaises(TypeError, hash, d)
Georg Brandl48545522008-02-02 10:12:36 +00003308 del C.__hash__
3309 self.assertEqual(hash(d), 42)
Nick Coghlan53663a62008-07-15 14:27:37 +00003310 A.__hash__ = None
3311 self.assertRaises(TypeError, hash, d)
Georg Brandl48545522008-02-02 10:12:36 +00003312 del A.__hash__
3313 self.assertEqual(hash(d), orig_hash)
3314 d.foo = 42
3315 d.bar = 42
3316 self.assertEqual(d.foo, 42)
3317 self.assertEqual(d.bar, 42)
3318 def __getattribute__(self, name):
3319 if name == "foo":
3320 return 24
3321 return object.__getattribute__(self, name)
3322 A.__getattribute__ = __getattribute__
3323 self.assertEqual(d.foo, 24)
3324 self.assertEqual(d.bar, 42)
3325 def __getattr__(self, name):
3326 if name in ("spam", "foo", "bar"):
3327 return "hello"
3328 raise AttributeError, name
3329 B.__getattr__ = __getattr__
3330 self.assertEqual(d.spam, "hello")
3331 self.assertEqual(d.foo, 24)
3332 self.assertEqual(d.bar, 42)
3333 del A.__getattribute__
3334 self.assertEqual(d.foo, 42)
3335 del d.foo
3336 self.assertEqual(d.foo, "hello")
3337 self.assertEqual(d.bar, 42)
3338 del B.__getattr__
3339 try:
3340 d.foo
3341 except AttributeError:
3342 pass
3343 else:
3344 self.fail("d.foo should be undefined now")
3345
3346 # Test a nasty bug in recurse_down_subclasses()
3347 import gc
3348 class A(object):
3349 pass
3350 class B(A):
3351 pass
3352 del B
3353 gc.collect()
3354 A.__setitem__ = lambda *a: None # crash
3355
3356 def test_buffer_inheritance(self):
3357 # Testing that buffer interface is inherited ...
3358
3359 import binascii
3360 # SF bug [#470040] ParseTuple t# vs subclasses.
3361
3362 class MyStr(str):
3363 pass
3364 base = 'abc'
3365 m = MyStr(base)
3366 # b2a_hex uses the buffer interface to get its argument's value, via
3367 # PyArg_ParseTuple 't#' code.
3368 self.assertEqual(binascii.b2a_hex(m), binascii.b2a_hex(base))
3369
3370 # It's not clear that unicode will continue to support the character
3371 # buffer interface, and this test will fail if that's taken away.
3372 class MyUni(unicode):
3373 pass
3374 base = u'abc'
3375 m = MyUni(base)
3376 self.assertEqual(binascii.b2a_hex(m), binascii.b2a_hex(base))
3377
3378 class MyInt(int):
3379 pass
3380 m = MyInt(42)
3381 try:
3382 binascii.b2a_hex(m)
3383 self.fail('subclass of int should not have a buffer interface')
3384 except TypeError:
3385 pass
3386
3387 def test_str_of_str_subclass(self):
3388 # Testing __str__ defined in subclass of str ...
3389 import binascii
3390 import cStringIO
3391
3392 class octetstring(str):
3393 def __str__(self):
3394 return binascii.b2a_hex(self)
3395 def __repr__(self):
3396 return self + " repr"
3397
3398 o = octetstring('A')
3399 self.assertEqual(type(o), octetstring)
3400 self.assertEqual(type(str(o)), str)
3401 self.assertEqual(type(repr(o)), str)
3402 self.assertEqual(ord(o), 0x41)
3403 self.assertEqual(str(o), '41')
3404 self.assertEqual(repr(o), 'A repr')
3405 self.assertEqual(o.__str__(), '41')
3406 self.assertEqual(o.__repr__(), 'A repr')
3407
3408 capture = cStringIO.StringIO()
3409 # Calling str() or not exercises different internal paths.
3410 print >> capture, o
3411 print >> capture, str(o)
3412 self.assertEqual(capture.getvalue(), '41\n41\n')
3413 capture.close()
3414
3415 def test_keyword_arguments(self):
3416 # Testing keyword arguments to __init__, __call__...
3417 def f(a): return a
3418 self.assertEqual(f.__call__(a=42), 42)
3419 a = []
3420 list.__init__(a, sequence=[0, 1, 2])
3421 self.assertEqual(a, [0, 1, 2])
3422
3423 def test_recursive_call(self):
3424 # Testing recursive __call__() by setting to instance of class...
3425 class A(object):
3426 pass
3427
3428 A.__call__ = A()
3429 try:
3430 A()()
3431 except RuntimeError:
3432 pass
3433 else:
3434 self.fail("Recursion limit should have been reached for __call__()")
3435
3436 def test_delete_hook(self):
3437 # Testing __del__ hook...
3438 log = []
3439 class C(object):
3440 def __del__(self):
3441 log.append(1)
3442 c = C()
3443 self.assertEqual(log, [])
3444 del c
3445 self.assertEqual(log, [1])
3446
3447 class D(object): pass
3448 d = D()
3449 try: del d[0]
3450 except TypeError: pass
3451 else: self.fail("invalid del() didn't raise TypeError")
3452
3453 def test_hash_inheritance(self):
3454 # Testing hash of mutable subclasses...
3455
3456 class mydict(dict):
3457 pass
3458 d = mydict()
3459 try:
3460 hash(d)
3461 except TypeError:
3462 pass
3463 else:
3464 self.fail("hash() of dict subclass should fail")
3465
3466 class mylist(list):
3467 pass
3468 d = mylist()
3469 try:
3470 hash(d)
3471 except TypeError:
3472 pass
3473 else:
3474 self.fail("hash() of list subclass should fail")
3475
3476 def test_str_operations(self):
3477 try: 'a' + 5
3478 except TypeError: pass
3479 else: self.fail("'' + 5 doesn't raise TypeError")
3480
3481 try: ''.split('')
3482 except ValueError: pass
3483 else: self.fail("''.split('') doesn't raise ValueError")
3484
3485 try: ''.join([0])
3486 except TypeError: pass
3487 else: self.fail("''.join([0]) doesn't raise TypeError")
3488
3489 try: ''.rindex('5')
3490 except ValueError: pass
3491 else: self.fail("''.rindex('5') doesn't raise ValueError")
3492
3493 try: '%(n)s' % None
3494 except TypeError: pass
3495 else: self.fail("'%(n)s' % None doesn't raise TypeError")
3496
3497 try: '%(n' % {}
3498 except ValueError: pass
3499 else: self.fail("'%(n' % {} '' doesn't raise ValueError")
3500
3501 try: '%*s' % ('abc')
3502 except TypeError: pass
3503 else: self.fail("'%*s' % ('abc') doesn't raise TypeError")
3504
3505 try: '%*.*s' % ('abc', 5)
3506 except TypeError: pass
3507 else: self.fail("'%*.*s' % ('abc', 5) doesn't raise TypeError")
3508
3509 try: '%s' % (1, 2)
3510 except TypeError: pass
3511 else: self.fail("'%s' % (1, 2) doesn't raise TypeError")
3512
3513 try: '%' % None
3514 except ValueError: pass
3515 else: self.fail("'%' % None doesn't raise ValueError")
3516
3517 self.assertEqual('534253'.isdigit(), 1)
3518 self.assertEqual('534253x'.isdigit(), 0)
3519 self.assertEqual('%c' % 5, '\x05')
3520 self.assertEqual('%c' % '5', '5')
3521
3522 def test_deepcopy_recursive(self):
3523 # Testing deepcopy of recursive objects...
3524 class Node:
3525 pass
3526 a = Node()
3527 b = Node()
3528 a.b = b
3529 b.a = a
3530 z = deepcopy(a) # This blew up before
3531
3532 def test_unintialized_modules(self):
3533 # Testing uninitialized module objects...
3534 from types import ModuleType as M
3535 m = M.__new__(M)
3536 str(m)
3537 self.assertEqual(hasattr(m, "__name__"), 0)
3538 self.assertEqual(hasattr(m, "__file__"), 0)
3539 self.assertEqual(hasattr(m, "foo"), 0)
3540 self.assertEqual(m.__dict__, None)
3541 m.foo = 1
3542 self.assertEqual(m.__dict__, {"foo": 1})
3543
3544 def test_funny_new(self):
3545 # Testing __new__ returning something unexpected...
3546 class C(object):
3547 def __new__(cls, arg):
3548 if isinstance(arg, str): return [1, 2, 3]
3549 elif isinstance(arg, int): return object.__new__(D)
3550 else: return object.__new__(cls)
3551 class D(C):
3552 def __init__(self, arg):
3553 self.foo = arg
3554 self.assertEqual(C("1"), [1, 2, 3])
3555 self.assertEqual(D("1"), [1, 2, 3])
3556 d = D(None)
3557 self.assertEqual(d.foo, None)
3558 d = C(1)
3559 self.assertEqual(isinstance(d, D), True)
3560 self.assertEqual(d.foo, 1)
3561 d = D(1)
3562 self.assertEqual(isinstance(d, D), True)
3563 self.assertEqual(d.foo, 1)
3564
3565 def test_imul_bug(self):
3566 # Testing for __imul__ problems...
3567 # SF bug 544647
3568 class C(object):
3569 def __imul__(self, other):
3570 return (self, other)
3571 x = C()
3572 y = x
3573 y *= 1.0
3574 self.assertEqual(y, (x, 1.0))
3575 y = x
3576 y *= 2
3577 self.assertEqual(y, (x, 2))
3578 y = x
3579 y *= 3L
3580 self.assertEqual(y, (x, 3L))
3581 y = x
3582 y *= 1L<<100
3583 self.assertEqual(y, (x, 1L<<100))
3584 y = x
3585 y *= None
3586 self.assertEqual(y, (x, None))
3587 y = x
3588 y *= "foo"
3589 self.assertEqual(y, (x, "foo"))
3590
3591 def test_copy_setstate(self):
3592 # Testing that copy.*copy() correctly uses __setstate__...
3593 import copy
3594 class C(object):
3595 def __init__(self, foo=None):
3596 self.foo = foo
3597 self.__foo = foo
3598 def setfoo(self, foo=None):
3599 self.foo = foo
3600 def getfoo(self):
3601 return self.__foo
3602 def __getstate__(self):
3603 return [self.foo]
3604 def __setstate__(self_, lst):
3605 self.assertEqual(len(lst), 1)
3606 self_.__foo = self_.foo = lst[0]
3607 a = C(42)
3608 a.setfoo(24)
3609 self.assertEqual(a.foo, 24)
3610 self.assertEqual(a.getfoo(), 42)
3611 b = copy.copy(a)
3612 self.assertEqual(b.foo, 24)
3613 self.assertEqual(b.getfoo(), 24)
3614 b = copy.deepcopy(a)
3615 self.assertEqual(b.foo, 24)
3616 self.assertEqual(b.getfoo(), 24)
3617
3618 def test_slices(self):
3619 # Testing cases with slices and overridden __getitem__ ...
3620
3621 # Strings
3622 self.assertEqual("hello"[:4], "hell")
3623 self.assertEqual("hello"[slice(4)], "hell")
3624 self.assertEqual(str.__getitem__("hello", slice(4)), "hell")
3625 class S(str):
3626 def __getitem__(self, x):
3627 return str.__getitem__(self, x)
3628 self.assertEqual(S("hello")[:4], "hell")
3629 self.assertEqual(S("hello")[slice(4)], "hell")
3630 self.assertEqual(S("hello").__getitem__(slice(4)), "hell")
3631 # Tuples
3632 self.assertEqual((1,2,3)[:2], (1,2))
3633 self.assertEqual((1,2,3)[slice(2)], (1,2))
3634 self.assertEqual(tuple.__getitem__((1,2,3), slice(2)), (1,2))
3635 class T(tuple):
3636 def __getitem__(self, x):
3637 return tuple.__getitem__(self, x)
3638 self.assertEqual(T((1,2,3))[:2], (1,2))
3639 self.assertEqual(T((1,2,3))[slice(2)], (1,2))
3640 self.assertEqual(T((1,2,3)).__getitem__(slice(2)), (1,2))
3641 # Lists
3642 self.assertEqual([1,2,3][:2], [1,2])
3643 self.assertEqual([1,2,3][slice(2)], [1,2])
3644 self.assertEqual(list.__getitem__([1,2,3], slice(2)), [1,2])
3645 class L(list):
3646 def __getitem__(self, x):
3647 return list.__getitem__(self, x)
3648 self.assertEqual(L([1,2,3])[:2], [1,2])
3649 self.assertEqual(L([1,2,3])[slice(2)], [1,2])
3650 self.assertEqual(L([1,2,3]).__getitem__(slice(2)), [1,2])
3651 # Now do lists and __setitem__
3652 a = L([1,2,3])
3653 a[slice(1, 3)] = [3,2]
3654 self.assertEqual(a, [1,3,2])
3655 a[slice(0, 2, 1)] = [3,1]
3656 self.assertEqual(a, [3,1,2])
3657 a.__setitem__(slice(1, 3), [2,1])
3658 self.assertEqual(a, [3,2,1])
3659 a.__setitem__(slice(0, 2, 1), [2,3])
3660 self.assertEqual(a, [2,3,1])
3661
3662 def test_subtype_resurrection(self):
3663 # Testing resurrection of new-style instance...
3664
3665 class C(object):
3666 container = []
3667
3668 def __del__(self):
3669 # resurrect the instance
3670 C.container.append(self)
3671
3672 c = C()
3673 c.attr = 42
3674
3675 # The most interesting thing here is whether this blows up, due to flawed
3676 # GC tracking logic in typeobject.c's call_finalizer() (a 2.2.1 bug).
3677 del c
3678
3679 # If that didn't blow up, it's also interesting to see whether clearing
3680 # the last container slot works: that will attempt to delete c again,
3681 # which will cause c to get appended back to the container again "during"
3682 # the del.
3683 del C.container[-1]
3684 self.assertEqual(len(C.container), 1)
3685 self.assertEqual(C.container[-1].attr, 42)
3686
3687 # Make c mortal again, so that the test framework with -l doesn't report
3688 # it as a leak.
3689 del C.__del__
3690
3691 def test_slots_trash(self):
3692 # Testing slot trash...
3693 # Deallocating deeply nested slotted trash caused stack overflows
3694 class trash(object):
3695 __slots__ = ['x']
3696 def __init__(self, x):
3697 self.x = x
3698 o = None
3699 for i in xrange(50000):
3700 o = trash(o)
3701 del o
3702
3703 def test_slots_multiple_inheritance(self):
3704 # SF bug 575229, multiple inheritance w/ slots dumps core
3705 class A(object):
3706 __slots__=()
3707 class B(object):
3708 pass
3709 class C(A,B) :
3710 __slots__=()
3711 self.assertEqual(C.__basicsize__, B.__basicsize__)
3712 self.assert_(hasattr(C, '__dict__'))
3713 self.assert_(hasattr(C, '__weakref__'))
3714 C().x = 2
3715
3716 def test_rmul(self):
3717 # Testing correct invocation of __rmul__...
3718 # SF patch 592646
3719 class C(object):
3720 def __mul__(self, other):
3721 return "mul"
3722 def __rmul__(self, other):
3723 return "rmul"
3724 a = C()
3725 self.assertEqual(a*2, "mul")
3726 self.assertEqual(a*2.2, "mul")
3727 self.assertEqual(2*a, "rmul")
3728 self.assertEqual(2.2*a, "rmul")
3729
3730 def test_ipow(self):
3731 # Testing correct invocation of __ipow__...
3732 # [SF bug 620179]
3733 class C(object):
3734 def __ipow__(self, other):
3735 pass
3736 a = C()
3737 a **= 2
3738
3739 def test_mutable_bases(self):
3740 # Testing mutable bases...
3741
3742 # stuff that should work:
3743 class C(object):
3744 pass
3745 class C2(object):
3746 def __getattribute__(self, attr):
3747 if attr == 'a':
3748 return 2
3749 else:
3750 return super(C2, self).__getattribute__(attr)
3751 def meth(self):
3752 return 1
3753 class D(C):
3754 pass
3755 class E(D):
3756 pass
3757 d = D()
3758 e = E()
3759 D.__bases__ = (C,)
3760 D.__bases__ = (C2,)
3761 self.assertEqual(d.meth(), 1)
3762 self.assertEqual(e.meth(), 1)
3763 self.assertEqual(d.a, 2)
3764 self.assertEqual(e.a, 2)
3765 self.assertEqual(C2.__subclasses__(), [D])
3766
3767 # stuff that shouldn't:
3768 class L(list):
3769 pass
3770
3771 try:
3772 L.__bases__ = (dict,)
3773 except TypeError:
3774 pass
3775 else:
3776 self.fail("shouldn't turn list subclass into dict subclass")
3777
3778 try:
3779 list.__bases__ = (dict,)
3780 except TypeError:
3781 pass
3782 else:
3783 self.fail("shouldn't be able to assign to list.__bases__")
3784
3785 try:
3786 D.__bases__ = (C2, list)
3787 except TypeError:
3788 pass
3789 else:
3790 assert 0, "best_base calculation found wanting"
3791
3792 try:
3793 del D.__bases__
3794 except TypeError:
3795 pass
3796 else:
3797 self.fail("shouldn't be able to delete .__bases__")
3798
3799 try:
3800 D.__bases__ = ()
3801 except TypeError, msg:
3802 if str(msg) == "a new-style class can't have only classic bases":
3803 self.fail("wrong error message for .__bases__ = ()")
3804 else:
3805 self.fail("shouldn't be able to set .__bases__ to ()")
3806
3807 try:
3808 D.__bases__ = (D,)
3809 except TypeError:
3810 pass
3811 else:
3812 # actually, we'll have crashed by here...
3813 self.fail("shouldn't be able to create inheritance cycles")
3814
3815 try:
3816 D.__bases__ = (C, C)
3817 except TypeError:
3818 pass
3819 else:
3820 self.fail("didn't detect repeated base classes")
3821
3822 try:
3823 D.__bases__ = (E,)
3824 except TypeError:
3825 pass
3826 else:
3827 self.fail("shouldn't be able to create inheritance cycles")
3828
3829 # let's throw a classic class into the mix:
3830 class Classic:
3831 def meth2(self):
3832 return 3
3833
3834 D.__bases__ = (C, Classic)
3835
3836 self.assertEqual(d.meth2(), 3)
3837 self.assertEqual(e.meth2(), 3)
3838 try:
3839 d.a
3840 except AttributeError:
3841 pass
3842 else:
3843 self.fail("attribute should have vanished")
3844
3845 try:
3846 D.__bases__ = (Classic,)
3847 except TypeError:
3848 pass
3849 else:
3850 self.fail("new-style class must have a new-style base")
3851
Benjamin Peterson4585ca92009-04-18 20:50:24 +00003852 def test_builtin_bases(self):
3853 # Make sure all the builtin types can have their base queried without
3854 # segfaulting. See issue #5787.
3855 builtin_types = [tp for tp in __builtin__.__dict__.itervalues()
3856 if isinstance(tp, type)]
3857 for tp in builtin_types:
3858 object.__getattribute__(tp, "__bases__")
3859 if tp is not object:
3860 self.assertEqual(len(tp.__bases__), 1, tp)
3861
3862
Georg Brandl48545522008-02-02 10:12:36 +00003863 def test_mutable_bases_with_failing_mro(self):
3864 # Testing mutable bases with failing mro...
3865 class WorkOnce(type):
3866 def __new__(self, name, bases, ns):
3867 self.flag = 0
3868 return super(WorkOnce, self).__new__(WorkOnce, name, bases, ns)
3869 def mro(self):
3870 if self.flag > 0:
3871 raise RuntimeError, "bozo"
3872 else:
3873 self.flag += 1
3874 return type.mro(self)
3875
3876 class WorkAlways(type):
3877 def mro(self):
3878 # this is here to make sure that .mro()s aren't called
3879 # with an exception set (which was possible at one point).
3880 # An error message will be printed in a debug build.
3881 # What's a good way to test for this?
Michael W. Hudson586da8f2002-11-27 15:20:19 +00003882 return type.mro(self)
3883
Georg Brandl48545522008-02-02 10:12:36 +00003884 class C(object):
3885 pass
Michael W. Hudson586da8f2002-11-27 15:20:19 +00003886
Georg Brandl48545522008-02-02 10:12:36 +00003887 class C2(object):
3888 pass
Michael W. Hudson586da8f2002-11-27 15:20:19 +00003889
Georg Brandl48545522008-02-02 10:12:36 +00003890 class D(C):
3891 pass
Michael W. Hudson586da8f2002-11-27 15:20:19 +00003892
Georg Brandl48545522008-02-02 10:12:36 +00003893 class E(D):
3894 pass
Michael W. Hudson586da8f2002-11-27 15:20:19 +00003895
Georg Brandl48545522008-02-02 10:12:36 +00003896 class F(D):
3897 __metaclass__ = WorkOnce
Michael W. Hudson586da8f2002-11-27 15:20:19 +00003898
Georg Brandl48545522008-02-02 10:12:36 +00003899 class G(D):
3900 __metaclass__ = WorkAlways
Michael W. Hudson586da8f2002-11-27 15:20:19 +00003901
Georg Brandl48545522008-02-02 10:12:36 +00003902 # Immediate subclasses have their mro's adjusted in alphabetical
3903 # order, so E's will get adjusted before adjusting F's fails. We
3904 # check here that E's gets restored.
Michael W. Hudson586da8f2002-11-27 15:20:19 +00003905
Georg Brandl48545522008-02-02 10:12:36 +00003906 E_mro_before = E.__mro__
3907 D_mro_before = D.__mro__
Armin Rigofd163f92005-12-29 15:59:19 +00003908
Armin Rigofd163f92005-12-29 15:59:19 +00003909 try:
Georg Brandl48545522008-02-02 10:12:36 +00003910 D.__bases__ = (C2,)
3911 except RuntimeError:
3912 self.assertEqual(E.__mro__, E_mro_before)
3913 self.assertEqual(D.__mro__, D_mro_before)
3914 else:
3915 self.fail("exception not propagated")
3916
3917 def test_mutable_bases_catch_mro_conflict(self):
3918 # Testing mutable bases catch mro conflict...
3919 class A(object):
3920 pass
3921
3922 class B(object):
3923 pass
3924
3925 class C(A, B):
3926 pass
3927
3928 class D(A, B):
3929 pass
3930
3931 class E(C, D):
3932 pass
3933
3934 try:
3935 C.__bases__ = (B, A)
Armin Rigofd163f92005-12-29 15:59:19 +00003936 except TypeError:
3937 pass
3938 else:
Georg Brandl48545522008-02-02 10:12:36 +00003939 self.fail("didn't catch MRO conflict")
Armin Rigofd163f92005-12-29 15:59:19 +00003940
Georg Brandl48545522008-02-02 10:12:36 +00003941 def test_mutable_names(self):
3942 # Testing mutable names...
3943 class C(object):
3944 pass
3945
3946 # C.__module__ could be 'test_descr' or '__main__'
3947 mod = C.__module__
3948
3949 C.__name__ = 'D'
3950 self.assertEqual((C.__module__, C.__name__), (mod, 'D'))
3951
3952 C.__name__ = 'D.E'
3953 self.assertEqual((C.__module__, C.__name__), (mod, 'D.E'))
3954
3955 def test_subclass_right_op(self):
3956 # Testing correct dispatch of subclass overloading __r<op>__...
3957
3958 # This code tests various cases where right-dispatch of a subclass
3959 # should be preferred over left-dispatch of a base class.
3960
3961 # Case 1: subclass of int; this tests code in abstract.c::binary_op1()
3962
3963 class B(int):
3964 def __floordiv__(self, other):
3965 return "B.__floordiv__"
3966 def __rfloordiv__(self, other):
3967 return "B.__rfloordiv__"
3968
3969 self.assertEqual(B(1) // 1, "B.__floordiv__")
3970 self.assertEqual(1 // B(1), "B.__rfloordiv__")
3971
3972 # Case 2: subclass of object; this is just the baseline for case 3
3973
3974 class C(object):
3975 def __floordiv__(self, other):
3976 return "C.__floordiv__"
3977 def __rfloordiv__(self, other):
3978 return "C.__rfloordiv__"
3979
3980 self.assertEqual(C() // 1, "C.__floordiv__")
3981 self.assertEqual(1 // C(), "C.__rfloordiv__")
3982
3983 # Case 3: subclass of new-style class; here it gets interesting
3984
3985 class D(C):
3986 def __floordiv__(self, other):
3987 return "D.__floordiv__"
3988 def __rfloordiv__(self, other):
3989 return "D.__rfloordiv__"
3990
3991 self.assertEqual(D() // C(), "D.__floordiv__")
3992 self.assertEqual(C() // D(), "D.__rfloordiv__")
3993
3994 # Case 4: this didn't work right in 2.2.2 and 2.3a1
3995
3996 class E(C):
3997 pass
3998
3999 self.assertEqual(E.__rfloordiv__, C.__rfloordiv__)
4000
4001 self.assertEqual(E() // 1, "C.__floordiv__")
4002 self.assertEqual(1 // E(), "C.__rfloordiv__")
4003 self.assertEqual(E() // C(), "C.__floordiv__")
4004 self.assertEqual(C() // E(), "C.__floordiv__") # This one would fail
4005
4006 def test_meth_class_get(self):
4007 # Testing __get__ method of METH_CLASS C methods...
4008 # Full coverage of descrobject.c::classmethod_get()
4009
4010 # Baseline
4011 arg = [1, 2, 3]
4012 res = {1: None, 2: None, 3: None}
4013 self.assertEqual(dict.fromkeys(arg), res)
4014 self.assertEqual({}.fromkeys(arg), res)
4015
4016 # Now get the descriptor
4017 descr = dict.__dict__["fromkeys"]
4018
4019 # More baseline using the descriptor directly
4020 self.assertEqual(descr.__get__(None, dict)(arg), res)
4021 self.assertEqual(descr.__get__({})(arg), res)
4022
4023 # Now check various error cases
4024 try:
4025 descr.__get__(None, None)
4026 except TypeError:
4027 pass
4028 else:
4029 self.fail("shouldn't have allowed descr.__get__(None, None)")
4030 try:
4031 descr.__get__(42)
4032 except TypeError:
4033 pass
4034 else:
4035 self.fail("shouldn't have allowed descr.__get__(42)")
4036 try:
4037 descr.__get__(None, 42)
4038 except TypeError:
4039 pass
4040 else:
4041 self.fail("shouldn't have allowed descr.__get__(None, 42)")
4042 try:
4043 descr.__get__(None, int)
4044 except TypeError:
4045 pass
4046 else:
4047 self.fail("shouldn't have allowed descr.__get__(None, int)")
4048
4049 def test_isinst_isclass(self):
4050 # Testing proxy isinstance() and isclass()...
4051 class Proxy(object):
4052 def __init__(self, obj):
4053 self.__obj = obj
4054 def __getattribute__(self, name):
4055 if name.startswith("_Proxy__"):
4056 return object.__getattribute__(self, name)
4057 else:
4058 return getattr(self.__obj, name)
4059 # Test with a classic class
4060 class C:
4061 pass
4062 a = C()
4063 pa = Proxy(a)
4064 self.assert_(isinstance(a, C)) # Baseline
4065 self.assert_(isinstance(pa, C)) # Test
4066 # Test with a classic subclass
4067 class D(C):
4068 pass
4069 a = D()
4070 pa = Proxy(a)
4071 self.assert_(isinstance(a, C)) # Baseline
4072 self.assert_(isinstance(pa, C)) # Test
4073 # Test with a new-style class
4074 class C(object):
4075 pass
4076 a = C()
4077 pa = Proxy(a)
4078 self.assert_(isinstance(a, C)) # Baseline
4079 self.assert_(isinstance(pa, C)) # Test
4080 # Test with a new-style subclass
4081 class D(C):
4082 pass
4083 a = D()
4084 pa = Proxy(a)
4085 self.assert_(isinstance(a, C)) # Baseline
4086 self.assert_(isinstance(pa, C)) # Test
4087
4088 def test_proxy_super(self):
4089 # Testing super() for a proxy object...
4090 class Proxy(object):
4091 def __init__(self, obj):
4092 self.__obj = obj
4093 def __getattribute__(self, name):
4094 if name.startswith("_Proxy__"):
4095 return object.__getattribute__(self, name)
4096 else:
4097 return getattr(self.__obj, name)
4098
4099 class B(object):
4100 def f(self):
4101 return "B.f"
4102
4103 class C(B):
4104 def f(self):
4105 return super(C, self).f() + "->C.f"
4106
4107 obj = C()
4108 p = Proxy(obj)
4109 self.assertEqual(C.__dict__["f"](p), "B.f->C.f")
4110
4111 def test_carloverre(self):
4112 # Testing prohibition of Carlo Verre's hack...
4113 try:
4114 object.__setattr__(str, "foo", 42)
4115 except TypeError:
4116 pass
4117 else:
4118 self.fail("Carlo Verre __setattr__ suceeded!")
4119 try:
4120 object.__delattr__(str, "lower")
4121 except TypeError:
4122 pass
4123 else:
4124 self.fail("Carlo Verre __delattr__ succeeded!")
4125
4126 def test_weakref_segfault(self):
4127 # Testing weakref segfault...
4128 # SF 742911
4129 import weakref
4130
4131 class Provoker:
4132 def __init__(self, referrent):
4133 self.ref = weakref.ref(referrent)
4134
4135 def __del__(self):
4136 x = self.ref()
4137
4138 class Oops(object):
4139 pass
4140
4141 o = Oops()
4142 o.whatever = Provoker(o)
4143 del o
4144
4145 def test_wrapper_segfault(self):
4146 # SF 927248: deeply nested wrappers could cause stack overflow
4147 f = lambda:None
4148 for i in xrange(1000000):
4149 f = f.__call__
4150 f = None
4151
4152 def test_file_fault(self):
4153 # Testing sys.stdout is changed in getattr...
4154 import sys
4155 class StdoutGuard:
4156 def __getattr__(self, attr):
4157 sys.stdout = sys.__stdout__
4158 raise RuntimeError("Premature access to sys.stdout.%s" % attr)
4159 sys.stdout = StdoutGuard()
4160 try:
4161 print "Oops!"
4162 except RuntimeError:
4163 pass
4164
4165 def test_vicious_descriptor_nonsense(self):
4166 # Testing vicious_descriptor_nonsense...
4167
4168 # A potential segfault spotted by Thomas Wouters in mail to
4169 # python-dev 2003-04-17, turned into an example & fixed by Michael
4170 # Hudson just less than four months later...
4171
4172 class Evil(object):
4173 def __hash__(self):
4174 return hash('attr')
4175 def __eq__(self, other):
4176 del C.attr
4177 return 0
4178
4179 class Descr(object):
4180 def __get__(self, ob, type=None):
4181 return 1
4182
4183 class C(object):
4184 attr = Descr()
4185
4186 c = C()
4187 c.__dict__[Evil()] = 0
4188
4189 self.assertEqual(c.attr, 1)
4190 # this makes a crash more likely:
4191 import gc; gc.collect()
4192 self.assertEqual(hasattr(c, 'attr'), False)
4193
4194 def test_init(self):
4195 # SF 1155938
4196 class Foo(object):
4197 def __init__(self):
4198 return 10
4199 try:
4200 Foo()
4201 except TypeError:
4202 pass
4203 else:
4204 self.fail("did not test __init__() for None return")
4205
4206 def test_method_wrapper(self):
4207 # Testing method-wrapper objects...
4208 # <type 'method-wrapper'> did not support any reflection before 2.5
4209
4210 l = []
4211 self.assertEqual(l.__add__, l.__add__)
4212 self.assertEqual(l.__add__, [].__add__)
4213 self.assert_(l.__add__ != [5].__add__)
4214 self.assert_(l.__add__ != l.__mul__)
4215 self.assert_(l.__add__.__name__ == '__add__')
4216 self.assert_(l.__add__.__self__ is l)
4217 self.assert_(l.__add__.__objclass__ is list)
4218 self.assertEqual(l.__add__.__doc__, list.__add__.__doc__)
4219 try:
4220 hash(l.__add__)
4221 except TypeError:
4222 pass
4223 else:
4224 self.fail("no TypeError from hash([].__add__)")
4225
4226 t = ()
4227 t += (7,)
4228 self.assertEqual(t.__add__, (7,).__add__)
4229 self.assertEqual(hash(t.__add__), hash((7,).__add__))
4230
4231 def test_not_implemented(self):
4232 # Testing NotImplemented...
4233 # all binary methods should be able to return a NotImplemented
4234 import sys
4235 import types
4236 import operator
4237
4238 def specialmethod(self, other):
4239 return NotImplemented
4240
4241 def check(expr, x, y):
4242 try:
4243 exec expr in {'x': x, 'y': y, 'operator': operator}
4244 except TypeError:
4245 pass
Armin Rigofd163f92005-12-29 15:59:19 +00004246 else:
Georg Brandl48545522008-02-02 10:12:36 +00004247 self.fail("no TypeError from %r" % (expr,))
Armin Rigofd163f92005-12-29 15:59:19 +00004248
Georg Brandl48545522008-02-02 10:12:36 +00004249 N1 = sys.maxint + 1L # might trigger OverflowErrors instead of
4250 # TypeErrors
4251 N2 = sys.maxint # if sizeof(int) < sizeof(long), might trigger
4252 # ValueErrors instead of TypeErrors
4253 for metaclass in [type, types.ClassType]:
4254 for name, expr, iexpr in [
4255 ('__add__', 'x + y', 'x += y'),
4256 ('__sub__', 'x - y', 'x -= y'),
4257 ('__mul__', 'x * y', 'x *= y'),
4258 ('__truediv__', 'operator.truediv(x, y)', None),
4259 ('__floordiv__', 'operator.floordiv(x, y)', None),
4260 ('__div__', 'x / y', 'x /= y'),
4261 ('__mod__', 'x % y', 'x %= y'),
4262 ('__divmod__', 'divmod(x, y)', None),
4263 ('__pow__', 'x ** y', 'x **= y'),
4264 ('__lshift__', 'x << y', 'x <<= y'),
4265 ('__rshift__', 'x >> y', 'x >>= y'),
4266 ('__and__', 'x & y', 'x &= y'),
4267 ('__or__', 'x | y', 'x |= y'),
4268 ('__xor__', 'x ^ y', 'x ^= y'),
4269 ('__coerce__', 'coerce(x, y)', None)]:
4270 if name == '__coerce__':
4271 rname = name
4272 else:
4273 rname = '__r' + name[2:]
4274 A = metaclass('A', (), {name: specialmethod})
4275 B = metaclass('B', (), {rname: specialmethod})
4276 a = A()
4277 b = B()
4278 check(expr, a, a)
4279 check(expr, a, b)
4280 check(expr, b, a)
4281 check(expr, b, b)
4282 check(expr, a, N1)
4283 check(expr, a, N2)
4284 check(expr, N1, b)
4285 check(expr, N2, b)
4286 if iexpr:
4287 check(iexpr, a, a)
4288 check(iexpr, a, b)
4289 check(iexpr, b, a)
4290 check(iexpr, b, b)
4291 check(iexpr, a, N1)
4292 check(iexpr, a, N2)
4293 iname = '__i' + name[2:]
4294 C = metaclass('C', (), {iname: specialmethod})
4295 c = C()
4296 check(iexpr, c, a)
4297 check(iexpr, c, b)
4298 check(iexpr, c, N1)
4299 check(iexpr, c, N2)
Georg Brandl0fca97a2007-03-05 22:28:08 +00004300
Georg Brandl48545522008-02-02 10:12:36 +00004301 def test_assign_slice(self):
4302 # ceval.c's assign_slice used to check for
4303 # tp->tp_as_sequence->sq_slice instead of
4304 # tp->tp_as_sequence->sq_ass_slice
Georg Brandl0fca97a2007-03-05 22:28:08 +00004305
Georg Brandl48545522008-02-02 10:12:36 +00004306 class C(object):
4307 def __setslice__(self, start, stop, value):
4308 self.value = value
Georg Brandl0fca97a2007-03-05 22:28:08 +00004309
Georg Brandl48545522008-02-02 10:12:36 +00004310 c = C()
4311 c[1:2] = 3
4312 self.assertEqual(c.value, 3)
Guido van Rossum9acc3872008-01-23 23:23:43 +00004313
Benjamin Peterson9adae2e2008-11-17 22:44:30 +00004314 def test_getattr_hooks(self):
4315 # issue 4230
4316
4317 class Descriptor(object):
4318 counter = 0
4319 def __get__(self, obj, objtype=None):
4320 def getter(name):
4321 self.counter += 1
4322 raise AttributeError(name)
4323 return getter
4324
4325 descr = Descriptor()
4326 class A(object):
4327 __getattribute__ = descr
4328 class B(object):
4329 __getattr__ = descr
4330 class C(object):
4331 __getattribute__ = descr
4332 __getattr__ = descr
4333
4334 self.assertRaises(AttributeError, getattr, A(), "attr")
4335 self.assertEquals(descr.counter, 1)
4336 self.assertRaises(AttributeError, getattr, B(), "attr")
4337 self.assertEquals(descr.counter, 2)
4338 self.assertRaises(AttributeError, getattr, C(), "attr")
4339 self.assertEquals(descr.counter, 4)
4340
4341 import gc
4342 class EvilGetattribute(object):
4343 # This used to segfault
4344 def __getattr__(self, name):
4345 raise AttributeError(name)
4346 def __getattribute__(self, name):
4347 del EvilGetattribute.__getattr__
4348 for i in range(5):
4349 gc.collect()
4350 raise AttributeError(name)
4351
4352 self.assertRaises(AttributeError, getattr, EvilGetattribute(), "attr")
4353
Guido van Rossum9acc3872008-01-23 23:23:43 +00004354
Georg Brandl48545522008-02-02 10:12:36 +00004355class DictProxyTests(unittest.TestCase):
4356 def setUp(self):
4357 class C(object):
4358 def meth(self):
4359 pass
4360 self.C = C
Guido van Rossum9acc3872008-01-23 23:23:43 +00004361
Georg Brandl48545522008-02-02 10:12:36 +00004362 def test_iter_keys(self):
4363 # Testing dict-proxy iterkeys...
4364 keys = [ key for key in self.C.__dict__.iterkeys() ]
4365 keys.sort()
4366 self.assertEquals(keys, ['__dict__', '__doc__', '__module__',
4367 '__weakref__', 'meth'])
Guido van Rossum9acc3872008-01-23 23:23:43 +00004368
Georg Brandl48545522008-02-02 10:12:36 +00004369 def test_iter_values(self):
4370 # Testing dict-proxy itervalues...
4371 values = [ values for values in self.C.__dict__.itervalues() ]
4372 self.assertEqual(len(values), 5)
Guido van Rossum9acc3872008-01-23 23:23:43 +00004373
Georg Brandl48545522008-02-02 10:12:36 +00004374 def test_iter_items(self):
4375 # Testing dict-proxy iteritems...
4376 keys = [ key for (key, value) in self.C.__dict__.iteritems() ]
4377 keys.sort()
4378 self.assertEqual(keys, ['__dict__', '__doc__', '__module__',
4379 '__weakref__', 'meth'])
Guido van Rossum9acc3872008-01-23 23:23:43 +00004380
Georg Brandl48545522008-02-02 10:12:36 +00004381 def test_dict_type_with_metaclass(self):
4382 # Testing type of __dict__ when __metaclass__ set...
4383 class B(object):
4384 pass
4385 class M(type):
4386 pass
4387 class C:
4388 # In 2.3a1, C.__dict__ was a real dict rather than a dict proxy
4389 __metaclass__ = M
4390 self.assertEqual(type(C.__dict__), type(B.__dict__))
Guido van Rossum9acc3872008-01-23 23:23:43 +00004391
Guido van Rossum9acc3872008-01-23 23:23:43 +00004392
Georg Brandl48545522008-02-02 10:12:36 +00004393class PTypesLongInitTest(unittest.TestCase):
4394 # This is in its own TestCase so that it can be run before any other tests.
4395 def test_pytype_long_ready(self):
4396 # Testing SF bug 551412 ...
Guido van Rossum9acc3872008-01-23 23:23:43 +00004397
Georg Brandl48545522008-02-02 10:12:36 +00004398 # This dumps core when SF bug 551412 isn't fixed --
4399 # but only when test_descr.py is run separately.
4400 # (That can't be helped -- as soon as PyType_Ready()
4401 # is called for PyLong_Type, the bug is gone.)
4402 class UserLong(object):
4403 def __pow__(self, *args):
4404 pass
4405 try:
4406 pow(0L, UserLong(), 0L)
4407 except:
4408 pass
Guido van Rossum9acc3872008-01-23 23:23:43 +00004409
Georg Brandl48545522008-02-02 10:12:36 +00004410 # Another segfault only when run early
4411 # (before PyType_Ready(tuple) is called)
4412 type.mro(tuple)
Guido van Rossum37edeab2008-01-24 17:58:05 +00004413
4414
Guido van Rossuma56b42b2001-09-20 21:39:07 +00004415def test_main():
Georg Brandl48545522008-02-02 10:12:36 +00004416 # Run all local test cases, with PTypesLongInitTest first.
4417 test_support.run_unittest(PTypesLongInitTest, OperatorsTest,
4418 ClassPropertiesAndMethods, DictProxyTests)
Tim Peters6d6c1a32001-08-02 04:15:00 +00004419
Guido van Rossuma56b42b2001-09-20 21:39:07 +00004420if __name__ == "__main__":
4421 test_main()