blob: 554e1c8a65a95e29b194fdabf901723b634ca0a6 [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
2962 def test_set_dict(self):
2963 # Testing __dict__ assignment...
2964 class C(object): pass
2965 a = C()
2966 a.__dict__ = {'b': 1}
2967 self.assertEqual(a.b, 1)
2968 def cant(x, dict):
2969 try:
2970 x.__dict__ = dict
2971 except (AttributeError, TypeError):
2972 pass
2973 else:
2974 self.fail("shouldn't allow %r.__dict__ = %r" % (x, dict))
2975 cant(a, None)
2976 cant(a, [])
2977 cant(a, 1)
2978 del a.__dict__ # Deleting __dict__ is allowed
2979
2980 class Base(object):
2981 pass
2982 def verify_dict_readonly(x):
2983 """
2984 x has to be an instance of a class inheriting from Base.
2985 """
2986 cant(x, {})
2987 try:
2988 del x.__dict__
2989 except (AttributeError, TypeError):
2990 pass
2991 else:
2992 self.fail("shouldn't allow del %r.__dict__" % x)
2993 dict_descr = Base.__dict__["__dict__"]
2994 try:
2995 dict_descr.__set__(x, {})
2996 except (AttributeError, TypeError):
2997 pass
2998 else:
2999 self.fail("dict_descr allowed access to %r's dict" % x)
3000
3001 # Classes don't allow __dict__ assignment and have readonly dicts
3002 class Meta1(type, Base):
3003 pass
3004 class Meta2(Base, type):
3005 pass
3006 class D(object):
3007 __metaclass__ = Meta1
3008 class E(object):
3009 __metaclass__ = Meta2
3010 for cls in C, D, E:
3011 verify_dict_readonly(cls)
3012 class_dict = cls.__dict__
3013 try:
3014 class_dict["spam"] = "eggs"
3015 except TypeError:
3016 pass
3017 else:
3018 self.fail("%r's __dict__ can be modified" % cls)
3019
3020 # Modules also disallow __dict__ assignment
3021 class Module1(types.ModuleType, Base):
3022 pass
3023 class Module2(Base, types.ModuleType):
3024 pass
3025 for ModuleType in Module1, Module2:
3026 mod = ModuleType("spam")
3027 verify_dict_readonly(mod)
3028 mod.__dict__["spam"] = "eggs"
3029
3030 # Exception's __dict__ can be replaced, but not deleted
3031 class Exception1(Exception, Base):
3032 pass
3033 class Exception2(Base, Exception):
3034 pass
3035 for ExceptionType in Exception, Exception1, Exception2:
3036 e = ExceptionType()
3037 e.__dict__ = {"a": 1}
3038 self.assertEqual(e.a, 1)
3039 try:
3040 del e.__dict__
3041 except (TypeError, AttributeError):
3042 pass
3043 else:
3044 self.fail("%r's __dict__ can be deleted" % e)
3045
3046 def test_pickles(self):
3047 # Testing pickling and copying new-style classes and objects...
3048 import pickle, cPickle
3049
3050 def sorteditems(d):
3051 L = d.items()
3052 L.sort()
3053 return L
3054
3055 global C
3056 class C(object):
3057 def __init__(self, a, b):
3058 super(C, self).__init__()
3059 self.a = a
3060 self.b = b
3061 def __repr__(self):
3062 return "C(%r, %r)" % (self.a, self.b)
3063
3064 global C1
3065 class C1(list):
3066 def __new__(cls, a, b):
3067 return super(C1, cls).__new__(cls)
3068 def __getnewargs__(self):
3069 return (self.a, self.b)
3070 def __init__(self, a, b):
3071 self.a = a
3072 self.b = b
3073 def __repr__(self):
3074 return "C1(%r, %r)<%r>" % (self.a, self.b, list(self))
3075
3076 global C2
3077 class C2(int):
3078 def __new__(cls, a, b, val=0):
3079 return super(C2, cls).__new__(cls, val)
3080 def __getnewargs__(self):
3081 return (self.a, self.b, int(self))
3082 def __init__(self, a, b, val=0):
3083 self.a = a
3084 self.b = b
3085 def __repr__(self):
3086 return "C2(%r, %r)<%r>" % (self.a, self.b, int(self))
3087
3088 global C3
3089 class C3(object):
3090 def __init__(self, foo):
3091 self.foo = foo
3092 def __getstate__(self):
3093 return self.foo
3094 def __setstate__(self, foo):
3095 self.foo = foo
3096
3097 global C4classic, C4
3098 class C4classic: # classic
3099 pass
3100 class C4(C4classic, object): # mixed inheritance
3101 pass
3102
3103 for p in pickle, cPickle:
3104 for bin in 0, 1:
3105 for cls in C, C1, C2:
3106 s = p.dumps(cls, bin)
3107 cls2 = p.loads(s)
3108 self.assert_(cls2 is cls)
3109
3110 a = C1(1, 2); a.append(42); a.append(24)
3111 b = C2("hello", "world", 42)
3112 s = p.dumps((a, b), bin)
3113 x, y = p.loads(s)
3114 self.assertEqual(x.__class__, a.__class__)
3115 self.assertEqual(sorteditems(x.__dict__), sorteditems(a.__dict__))
3116 self.assertEqual(y.__class__, b.__class__)
3117 self.assertEqual(sorteditems(y.__dict__), sorteditems(b.__dict__))
3118 self.assertEqual(repr(x), repr(a))
3119 self.assertEqual(repr(y), repr(b))
3120 # Test for __getstate__ and __setstate__ on new style class
3121 u = C3(42)
3122 s = p.dumps(u, bin)
3123 v = p.loads(s)
3124 self.assertEqual(u.__class__, v.__class__)
3125 self.assertEqual(u.foo, v.foo)
3126 # Test for picklability of hybrid class
3127 u = C4()
3128 u.foo = 42
3129 s = p.dumps(u, bin)
3130 v = p.loads(s)
3131 self.assertEqual(u.__class__, v.__class__)
3132 self.assertEqual(u.foo, v.foo)
3133
3134 # Testing copy.deepcopy()
3135 import copy
3136 for cls in C, C1, C2:
3137 cls2 = copy.deepcopy(cls)
3138 self.assert_(cls2 is cls)
3139
3140 a = C1(1, 2); a.append(42); a.append(24)
3141 b = C2("hello", "world", 42)
3142 x, y = copy.deepcopy((a, b))
3143 self.assertEqual(x.__class__, a.__class__)
3144 self.assertEqual(sorteditems(x.__dict__), sorteditems(a.__dict__))
3145 self.assertEqual(y.__class__, b.__class__)
3146 self.assertEqual(sorteditems(y.__dict__), sorteditems(b.__dict__))
3147 self.assertEqual(repr(x), repr(a))
3148 self.assertEqual(repr(y), repr(b))
3149
3150 def test_pickle_slots(self):
3151 # Testing pickling of classes with __slots__ ...
3152 import pickle, cPickle
3153 # Pickling of classes with __slots__ but without __getstate__ should fail
3154 global B, C, D, E
3155 class B(object):
3156 pass
3157 for base in [object, B]:
3158 class C(base):
3159 __slots__ = ['a']
3160 class D(C):
3161 pass
3162 try:
3163 pickle.dumps(C())
3164 except TypeError:
3165 pass
3166 else:
3167 self.fail("should fail: pickle C instance - %s" % base)
3168 try:
3169 cPickle.dumps(C())
3170 except TypeError:
3171 pass
3172 else:
3173 self.fail("should fail: cPickle C instance - %s" % base)
3174 try:
3175 pickle.dumps(C())
3176 except TypeError:
3177 pass
3178 else:
3179 self.fail("should fail: pickle D instance - %s" % base)
3180 try:
3181 cPickle.dumps(D())
3182 except TypeError:
3183 pass
3184 else:
3185 self.fail("should fail: cPickle D instance - %s" % base)
3186 # Give C a nice generic __getstate__ and __setstate__
3187 class C(base):
3188 __slots__ = ['a']
3189 def __getstate__(self):
3190 try:
3191 d = self.__dict__.copy()
3192 except AttributeError:
3193 d = {}
3194 for cls in self.__class__.__mro__:
3195 for sn in cls.__dict__.get('__slots__', ()):
3196 try:
3197 d[sn] = getattr(self, sn)
3198 except AttributeError:
3199 pass
3200 return d
3201 def __setstate__(self, d):
3202 for k, v in d.items():
3203 setattr(self, k, v)
3204 class D(C):
3205 pass
3206 # Now it should work
3207 x = C()
3208 y = pickle.loads(pickle.dumps(x))
3209 self.assertEqual(hasattr(y, 'a'), 0)
3210 y = cPickle.loads(cPickle.dumps(x))
3211 self.assertEqual(hasattr(y, 'a'), 0)
3212 x.a = 42
3213 y = pickle.loads(pickle.dumps(x))
3214 self.assertEqual(y.a, 42)
3215 y = cPickle.loads(cPickle.dumps(x))
3216 self.assertEqual(y.a, 42)
3217 x = D()
3218 x.a = 42
3219 x.b = 100
3220 y = pickle.loads(pickle.dumps(x))
3221 self.assertEqual(y.a + y.b, 142)
3222 y = cPickle.loads(cPickle.dumps(x))
3223 self.assertEqual(y.a + y.b, 142)
3224 # A subclass that adds a slot should also work
3225 class E(C):
3226 __slots__ = ['b']
3227 x = E()
3228 x.a = 42
3229 x.b = "foo"
3230 y = pickle.loads(pickle.dumps(x))
3231 self.assertEqual(y.a, x.a)
3232 self.assertEqual(y.b, x.b)
3233 y = cPickle.loads(cPickle.dumps(x))
3234 self.assertEqual(y.a, x.a)
3235 self.assertEqual(y.b, x.b)
3236
3237 def test_binary_operator_override(self):
3238 # Testing overrides of binary operations...
3239 class I(int):
3240 def __repr__(self):
3241 return "I(%r)" % int(self)
3242 def __add__(self, other):
3243 return I(int(self) + int(other))
3244 __radd__ = __add__
3245 def __pow__(self, other, mod=None):
3246 if mod is None:
3247 return I(pow(int(self), int(other)))
3248 else:
3249 return I(pow(int(self), int(other), int(mod)))
3250 def __rpow__(self, other, mod=None):
3251 if mod is None:
3252 return I(pow(int(other), int(self), mod))
3253 else:
3254 return I(pow(int(other), int(self), int(mod)))
3255
3256 self.assertEqual(repr(I(1) + I(2)), "I(3)")
3257 self.assertEqual(repr(I(1) + 2), "I(3)")
3258 self.assertEqual(repr(1 + I(2)), "I(3)")
3259 self.assertEqual(repr(I(2) ** I(3)), "I(8)")
3260 self.assertEqual(repr(2 ** I(3)), "I(8)")
3261 self.assertEqual(repr(I(2) ** 3), "I(8)")
3262 self.assertEqual(repr(pow(I(2), I(3), I(5))), "I(3)")
3263 class S(str):
3264 def __eq__(self, other):
3265 return self.lower() == other.lower()
Nick Coghlan48361f52008-08-11 15:45:58 +00003266 __hash__ = None # Silence Py3k warning
Georg Brandl48545522008-02-02 10:12:36 +00003267
3268 def test_subclass_propagation(self):
3269 # Testing propagation of slot functions to subclasses...
3270 class A(object):
3271 pass
3272 class B(A):
3273 pass
3274 class C(A):
3275 pass
3276 class D(B, C):
3277 pass
3278 d = D()
3279 orig_hash = hash(d) # related to id(d) in platform-dependent ways
3280 A.__hash__ = lambda self: 42
3281 self.assertEqual(hash(d), 42)
3282 C.__hash__ = lambda self: 314
3283 self.assertEqual(hash(d), 314)
3284 B.__hash__ = lambda self: 144
3285 self.assertEqual(hash(d), 144)
3286 D.__hash__ = lambda self: 100
3287 self.assertEqual(hash(d), 100)
Nick Coghlan53663a62008-07-15 14:27:37 +00003288 D.__hash__ = None
3289 self.assertRaises(TypeError, hash, d)
Georg Brandl48545522008-02-02 10:12:36 +00003290 del D.__hash__
3291 self.assertEqual(hash(d), 144)
Nick Coghlan53663a62008-07-15 14:27:37 +00003292 B.__hash__ = None
3293 self.assertRaises(TypeError, hash, d)
Georg Brandl48545522008-02-02 10:12:36 +00003294 del B.__hash__
3295 self.assertEqual(hash(d), 314)
Nick Coghlan53663a62008-07-15 14:27:37 +00003296 C.__hash__ = None
3297 self.assertRaises(TypeError, hash, d)
Georg Brandl48545522008-02-02 10:12:36 +00003298 del C.__hash__
3299 self.assertEqual(hash(d), 42)
Nick Coghlan53663a62008-07-15 14:27:37 +00003300 A.__hash__ = None
3301 self.assertRaises(TypeError, hash, d)
Georg Brandl48545522008-02-02 10:12:36 +00003302 del A.__hash__
3303 self.assertEqual(hash(d), orig_hash)
3304 d.foo = 42
3305 d.bar = 42
3306 self.assertEqual(d.foo, 42)
3307 self.assertEqual(d.bar, 42)
3308 def __getattribute__(self, name):
3309 if name == "foo":
3310 return 24
3311 return object.__getattribute__(self, name)
3312 A.__getattribute__ = __getattribute__
3313 self.assertEqual(d.foo, 24)
3314 self.assertEqual(d.bar, 42)
3315 def __getattr__(self, name):
3316 if name in ("spam", "foo", "bar"):
3317 return "hello"
3318 raise AttributeError, name
3319 B.__getattr__ = __getattr__
3320 self.assertEqual(d.spam, "hello")
3321 self.assertEqual(d.foo, 24)
3322 self.assertEqual(d.bar, 42)
3323 del A.__getattribute__
3324 self.assertEqual(d.foo, 42)
3325 del d.foo
3326 self.assertEqual(d.foo, "hello")
3327 self.assertEqual(d.bar, 42)
3328 del B.__getattr__
3329 try:
3330 d.foo
3331 except AttributeError:
3332 pass
3333 else:
3334 self.fail("d.foo should be undefined now")
3335
3336 # Test a nasty bug in recurse_down_subclasses()
3337 import gc
3338 class A(object):
3339 pass
3340 class B(A):
3341 pass
3342 del B
3343 gc.collect()
3344 A.__setitem__ = lambda *a: None # crash
3345
3346 def test_buffer_inheritance(self):
3347 # Testing that buffer interface is inherited ...
3348
3349 import binascii
3350 # SF bug [#470040] ParseTuple t# vs subclasses.
3351
3352 class MyStr(str):
3353 pass
3354 base = 'abc'
3355 m = MyStr(base)
3356 # b2a_hex uses the buffer interface to get its argument's value, via
3357 # PyArg_ParseTuple 't#' code.
3358 self.assertEqual(binascii.b2a_hex(m), binascii.b2a_hex(base))
3359
3360 # It's not clear that unicode will continue to support the character
3361 # buffer interface, and this test will fail if that's taken away.
3362 class MyUni(unicode):
3363 pass
3364 base = u'abc'
3365 m = MyUni(base)
3366 self.assertEqual(binascii.b2a_hex(m), binascii.b2a_hex(base))
3367
3368 class MyInt(int):
3369 pass
3370 m = MyInt(42)
3371 try:
3372 binascii.b2a_hex(m)
3373 self.fail('subclass of int should not have a buffer interface')
3374 except TypeError:
3375 pass
3376
3377 def test_str_of_str_subclass(self):
3378 # Testing __str__ defined in subclass of str ...
3379 import binascii
3380 import cStringIO
3381
3382 class octetstring(str):
3383 def __str__(self):
3384 return binascii.b2a_hex(self)
3385 def __repr__(self):
3386 return self + " repr"
3387
3388 o = octetstring('A')
3389 self.assertEqual(type(o), octetstring)
3390 self.assertEqual(type(str(o)), str)
3391 self.assertEqual(type(repr(o)), str)
3392 self.assertEqual(ord(o), 0x41)
3393 self.assertEqual(str(o), '41')
3394 self.assertEqual(repr(o), 'A repr')
3395 self.assertEqual(o.__str__(), '41')
3396 self.assertEqual(o.__repr__(), 'A repr')
3397
3398 capture = cStringIO.StringIO()
3399 # Calling str() or not exercises different internal paths.
3400 print >> capture, o
3401 print >> capture, str(o)
3402 self.assertEqual(capture.getvalue(), '41\n41\n')
3403 capture.close()
3404
3405 def test_keyword_arguments(self):
3406 # Testing keyword arguments to __init__, __call__...
3407 def f(a): return a
3408 self.assertEqual(f.__call__(a=42), 42)
3409 a = []
3410 list.__init__(a, sequence=[0, 1, 2])
3411 self.assertEqual(a, [0, 1, 2])
3412
3413 def test_recursive_call(self):
3414 # Testing recursive __call__() by setting to instance of class...
3415 class A(object):
3416 pass
3417
3418 A.__call__ = A()
3419 try:
3420 A()()
3421 except RuntimeError:
3422 pass
3423 else:
3424 self.fail("Recursion limit should have been reached for __call__()")
3425
3426 def test_delete_hook(self):
3427 # Testing __del__ hook...
3428 log = []
3429 class C(object):
3430 def __del__(self):
3431 log.append(1)
3432 c = C()
3433 self.assertEqual(log, [])
3434 del c
3435 self.assertEqual(log, [1])
3436
3437 class D(object): pass
3438 d = D()
3439 try: del d[0]
3440 except TypeError: pass
3441 else: self.fail("invalid del() didn't raise TypeError")
3442
3443 def test_hash_inheritance(self):
3444 # Testing hash of mutable subclasses...
3445
3446 class mydict(dict):
3447 pass
3448 d = mydict()
3449 try:
3450 hash(d)
3451 except TypeError:
3452 pass
3453 else:
3454 self.fail("hash() of dict subclass should fail")
3455
3456 class mylist(list):
3457 pass
3458 d = mylist()
3459 try:
3460 hash(d)
3461 except TypeError:
3462 pass
3463 else:
3464 self.fail("hash() of list subclass should fail")
3465
3466 def test_str_operations(self):
3467 try: 'a' + 5
3468 except TypeError: pass
3469 else: self.fail("'' + 5 doesn't raise TypeError")
3470
3471 try: ''.split('')
3472 except ValueError: pass
3473 else: self.fail("''.split('') doesn't raise ValueError")
3474
3475 try: ''.join([0])
3476 except TypeError: pass
3477 else: self.fail("''.join([0]) doesn't raise TypeError")
3478
3479 try: ''.rindex('5')
3480 except ValueError: pass
3481 else: self.fail("''.rindex('5') doesn't raise ValueError")
3482
3483 try: '%(n)s' % None
3484 except TypeError: pass
3485 else: self.fail("'%(n)s' % None doesn't raise TypeError")
3486
3487 try: '%(n' % {}
3488 except ValueError: pass
3489 else: self.fail("'%(n' % {} '' doesn't raise ValueError")
3490
3491 try: '%*s' % ('abc')
3492 except TypeError: pass
3493 else: self.fail("'%*s' % ('abc') doesn't raise TypeError")
3494
3495 try: '%*.*s' % ('abc', 5)
3496 except TypeError: pass
3497 else: self.fail("'%*.*s' % ('abc', 5) doesn't raise TypeError")
3498
3499 try: '%s' % (1, 2)
3500 except TypeError: pass
3501 else: self.fail("'%s' % (1, 2) doesn't raise TypeError")
3502
3503 try: '%' % None
3504 except ValueError: pass
3505 else: self.fail("'%' % None doesn't raise ValueError")
3506
3507 self.assertEqual('534253'.isdigit(), 1)
3508 self.assertEqual('534253x'.isdigit(), 0)
3509 self.assertEqual('%c' % 5, '\x05')
3510 self.assertEqual('%c' % '5', '5')
3511
3512 def test_deepcopy_recursive(self):
3513 # Testing deepcopy of recursive objects...
3514 class Node:
3515 pass
3516 a = Node()
3517 b = Node()
3518 a.b = b
3519 b.a = a
3520 z = deepcopy(a) # This blew up before
3521
3522 def test_unintialized_modules(self):
3523 # Testing uninitialized module objects...
3524 from types import ModuleType as M
3525 m = M.__new__(M)
3526 str(m)
3527 self.assertEqual(hasattr(m, "__name__"), 0)
3528 self.assertEqual(hasattr(m, "__file__"), 0)
3529 self.assertEqual(hasattr(m, "foo"), 0)
3530 self.assertEqual(m.__dict__, None)
3531 m.foo = 1
3532 self.assertEqual(m.__dict__, {"foo": 1})
3533
3534 def test_funny_new(self):
3535 # Testing __new__ returning something unexpected...
3536 class C(object):
3537 def __new__(cls, arg):
3538 if isinstance(arg, str): return [1, 2, 3]
3539 elif isinstance(arg, int): return object.__new__(D)
3540 else: return object.__new__(cls)
3541 class D(C):
3542 def __init__(self, arg):
3543 self.foo = arg
3544 self.assertEqual(C("1"), [1, 2, 3])
3545 self.assertEqual(D("1"), [1, 2, 3])
3546 d = D(None)
3547 self.assertEqual(d.foo, None)
3548 d = C(1)
3549 self.assertEqual(isinstance(d, D), True)
3550 self.assertEqual(d.foo, 1)
3551 d = D(1)
3552 self.assertEqual(isinstance(d, D), True)
3553 self.assertEqual(d.foo, 1)
3554
3555 def test_imul_bug(self):
3556 # Testing for __imul__ problems...
3557 # SF bug 544647
3558 class C(object):
3559 def __imul__(self, other):
3560 return (self, other)
3561 x = C()
3562 y = x
3563 y *= 1.0
3564 self.assertEqual(y, (x, 1.0))
3565 y = x
3566 y *= 2
3567 self.assertEqual(y, (x, 2))
3568 y = x
3569 y *= 3L
3570 self.assertEqual(y, (x, 3L))
3571 y = x
3572 y *= 1L<<100
3573 self.assertEqual(y, (x, 1L<<100))
3574 y = x
3575 y *= None
3576 self.assertEqual(y, (x, None))
3577 y = x
3578 y *= "foo"
3579 self.assertEqual(y, (x, "foo"))
3580
3581 def test_copy_setstate(self):
3582 # Testing that copy.*copy() correctly uses __setstate__...
3583 import copy
3584 class C(object):
3585 def __init__(self, foo=None):
3586 self.foo = foo
3587 self.__foo = foo
3588 def setfoo(self, foo=None):
3589 self.foo = foo
3590 def getfoo(self):
3591 return self.__foo
3592 def __getstate__(self):
3593 return [self.foo]
3594 def __setstate__(self_, lst):
3595 self.assertEqual(len(lst), 1)
3596 self_.__foo = self_.foo = lst[0]
3597 a = C(42)
3598 a.setfoo(24)
3599 self.assertEqual(a.foo, 24)
3600 self.assertEqual(a.getfoo(), 42)
3601 b = copy.copy(a)
3602 self.assertEqual(b.foo, 24)
3603 self.assertEqual(b.getfoo(), 24)
3604 b = copy.deepcopy(a)
3605 self.assertEqual(b.foo, 24)
3606 self.assertEqual(b.getfoo(), 24)
3607
3608 def test_slices(self):
3609 # Testing cases with slices and overridden __getitem__ ...
3610
3611 # Strings
3612 self.assertEqual("hello"[:4], "hell")
3613 self.assertEqual("hello"[slice(4)], "hell")
3614 self.assertEqual(str.__getitem__("hello", slice(4)), "hell")
3615 class S(str):
3616 def __getitem__(self, x):
3617 return str.__getitem__(self, x)
3618 self.assertEqual(S("hello")[:4], "hell")
3619 self.assertEqual(S("hello")[slice(4)], "hell")
3620 self.assertEqual(S("hello").__getitem__(slice(4)), "hell")
3621 # Tuples
3622 self.assertEqual((1,2,3)[:2], (1,2))
3623 self.assertEqual((1,2,3)[slice(2)], (1,2))
3624 self.assertEqual(tuple.__getitem__((1,2,3), slice(2)), (1,2))
3625 class T(tuple):
3626 def __getitem__(self, x):
3627 return tuple.__getitem__(self, x)
3628 self.assertEqual(T((1,2,3))[:2], (1,2))
3629 self.assertEqual(T((1,2,3))[slice(2)], (1,2))
3630 self.assertEqual(T((1,2,3)).__getitem__(slice(2)), (1,2))
3631 # Lists
3632 self.assertEqual([1,2,3][:2], [1,2])
3633 self.assertEqual([1,2,3][slice(2)], [1,2])
3634 self.assertEqual(list.__getitem__([1,2,3], slice(2)), [1,2])
3635 class L(list):
3636 def __getitem__(self, x):
3637 return list.__getitem__(self, x)
3638 self.assertEqual(L([1,2,3])[:2], [1,2])
3639 self.assertEqual(L([1,2,3])[slice(2)], [1,2])
3640 self.assertEqual(L([1,2,3]).__getitem__(slice(2)), [1,2])
3641 # Now do lists and __setitem__
3642 a = L([1,2,3])
3643 a[slice(1, 3)] = [3,2]
3644 self.assertEqual(a, [1,3,2])
3645 a[slice(0, 2, 1)] = [3,1]
3646 self.assertEqual(a, [3,1,2])
3647 a.__setitem__(slice(1, 3), [2,1])
3648 self.assertEqual(a, [3,2,1])
3649 a.__setitem__(slice(0, 2, 1), [2,3])
3650 self.assertEqual(a, [2,3,1])
3651
3652 def test_subtype_resurrection(self):
3653 # Testing resurrection of new-style instance...
3654
3655 class C(object):
3656 container = []
3657
3658 def __del__(self):
3659 # resurrect the instance
3660 C.container.append(self)
3661
3662 c = C()
3663 c.attr = 42
3664
3665 # The most interesting thing here is whether this blows up, due to flawed
3666 # GC tracking logic in typeobject.c's call_finalizer() (a 2.2.1 bug).
3667 del c
3668
3669 # If that didn't blow up, it's also interesting to see whether clearing
3670 # the last container slot works: that will attempt to delete c again,
3671 # which will cause c to get appended back to the container again "during"
3672 # the del.
3673 del C.container[-1]
3674 self.assertEqual(len(C.container), 1)
3675 self.assertEqual(C.container[-1].attr, 42)
3676
3677 # Make c mortal again, so that the test framework with -l doesn't report
3678 # it as a leak.
3679 del C.__del__
3680
3681 def test_slots_trash(self):
3682 # Testing slot trash...
3683 # Deallocating deeply nested slotted trash caused stack overflows
3684 class trash(object):
3685 __slots__ = ['x']
3686 def __init__(self, x):
3687 self.x = x
3688 o = None
3689 for i in xrange(50000):
3690 o = trash(o)
3691 del o
3692
3693 def test_slots_multiple_inheritance(self):
3694 # SF bug 575229, multiple inheritance w/ slots dumps core
3695 class A(object):
3696 __slots__=()
3697 class B(object):
3698 pass
3699 class C(A,B) :
3700 __slots__=()
3701 self.assertEqual(C.__basicsize__, B.__basicsize__)
3702 self.assert_(hasattr(C, '__dict__'))
3703 self.assert_(hasattr(C, '__weakref__'))
3704 C().x = 2
3705
3706 def test_rmul(self):
3707 # Testing correct invocation of __rmul__...
3708 # SF patch 592646
3709 class C(object):
3710 def __mul__(self, other):
3711 return "mul"
3712 def __rmul__(self, other):
3713 return "rmul"
3714 a = C()
3715 self.assertEqual(a*2, "mul")
3716 self.assertEqual(a*2.2, "mul")
3717 self.assertEqual(2*a, "rmul")
3718 self.assertEqual(2.2*a, "rmul")
3719
3720 def test_ipow(self):
3721 # Testing correct invocation of __ipow__...
3722 # [SF bug 620179]
3723 class C(object):
3724 def __ipow__(self, other):
3725 pass
3726 a = C()
3727 a **= 2
3728
3729 def test_mutable_bases(self):
3730 # Testing mutable bases...
3731
3732 # stuff that should work:
3733 class C(object):
3734 pass
3735 class C2(object):
3736 def __getattribute__(self, attr):
3737 if attr == 'a':
3738 return 2
3739 else:
3740 return super(C2, self).__getattribute__(attr)
3741 def meth(self):
3742 return 1
3743 class D(C):
3744 pass
3745 class E(D):
3746 pass
3747 d = D()
3748 e = E()
3749 D.__bases__ = (C,)
3750 D.__bases__ = (C2,)
3751 self.assertEqual(d.meth(), 1)
3752 self.assertEqual(e.meth(), 1)
3753 self.assertEqual(d.a, 2)
3754 self.assertEqual(e.a, 2)
3755 self.assertEqual(C2.__subclasses__(), [D])
3756
3757 # stuff that shouldn't:
3758 class L(list):
3759 pass
3760
3761 try:
3762 L.__bases__ = (dict,)
3763 except TypeError:
3764 pass
3765 else:
3766 self.fail("shouldn't turn list subclass into dict subclass")
3767
3768 try:
3769 list.__bases__ = (dict,)
3770 except TypeError:
3771 pass
3772 else:
3773 self.fail("shouldn't be able to assign to list.__bases__")
3774
3775 try:
3776 D.__bases__ = (C2, list)
3777 except TypeError:
3778 pass
3779 else:
3780 assert 0, "best_base calculation found wanting"
3781
3782 try:
3783 del D.__bases__
3784 except TypeError:
3785 pass
3786 else:
3787 self.fail("shouldn't be able to delete .__bases__")
3788
3789 try:
3790 D.__bases__ = ()
3791 except TypeError, msg:
3792 if str(msg) == "a new-style class can't have only classic bases":
3793 self.fail("wrong error message for .__bases__ = ()")
3794 else:
3795 self.fail("shouldn't be able to set .__bases__ to ()")
3796
3797 try:
3798 D.__bases__ = (D,)
3799 except TypeError:
3800 pass
3801 else:
3802 # actually, we'll have crashed by here...
3803 self.fail("shouldn't be able to create inheritance cycles")
3804
3805 try:
3806 D.__bases__ = (C, C)
3807 except TypeError:
3808 pass
3809 else:
3810 self.fail("didn't detect repeated base classes")
3811
3812 try:
3813 D.__bases__ = (E,)
3814 except TypeError:
3815 pass
3816 else:
3817 self.fail("shouldn't be able to create inheritance cycles")
3818
3819 # let's throw a classic class into the mix:
3820 class Classic:
3821 def meth2(self):
3822 return 3
3823
3824 D.__bases__ = (C, Classic)
3825
3826 self.assertEqual(d.meth2(), 3)
3827 self.assertEqual(e.meth2(), 3)
3828 try:
3829 d.a
3830 except AttributeError:
3831 pass
3832 else:
3833 self.fail("attribute should have vanished")
3834
3835 try:
3836 D.__bases__ = (Classic,)
3837 except TypeError:
3838 pass
3839 else:
3840 self.fail("new-style class must have a new-style base")
3841
Benjamin Peterson4585ca92009-04-18 20:50:24 +00003842 def test_builtin_bases(self):
3843 # Make sure all the builtin types can have their base queried without
3844 # segfaulting. See issue #5787.
3845 builtin_types = [tp for tp in __builtin__.__dict__.itervalues()
3846 if isinstance(tp, type)]
3847 for tp in builtin_types:
3848 object.__getattribute__(tp, "__bases__")
3849 if tp is not object:
3850 self.assertEqual(len(tp.__bases__), 1, tp)
3851
3852
Georg Brandl48545522008-02-02 10:12:36 +00003853 def test_mutable_bases_with_failing_mro(self):
3854 # Testing mutable bases with failing mro...
3855 class WorkOnce(type):
3856 def __new__(self, name, bases, ns):
3857 self.flag = 0
3858 return super(WorkOnce, self).__new__(WorkOnce, name, bases, ns)
3859 def mro(self):
3860 if self.flag > 0:
3861 raise RuntimeError, "bozo"
3862 else:
3863 self.flag += 1
3864 return type.mro(self)
3865
3866 class WorkAlways(type):
3867 def mro(self):
3868 # this is here to make sure that .mro()s aren't called
3869 # with an exception set (which was possible at one point).
3870 # An error message will be printed in a debug build.
3871 # What's a good way to test for this?
Michael W. Hudson586da8f2002-11-27 15:20:19 +00003872 return type.mro(self)
3873
Georg Brandl48545522008-02-02 10:12:36 +00003874 class C(object):
3875 pass
Michael W. Hudson586da8f2002-11-27 15:20:19 +00003876
Georg Brandl48545522008-02-02 10:12:36 +00003877 class C2(object):
3878 pass
Michael W. Hudson586da8f2002-11-27 15:20:19 +00003879
Georg Brandl48545522008-02-02 10:12:36 +00003880 class D(C):
3881 pass
Michael W. Hudson586da8f2002-11-27 15:20:19 +00003882
Georg Brandl48545522008-02-02 10:12:36 +00003883 class E(D):
3884 pass
Michael W. Hudson586da8f2002-11-27 15:20:19 +00003885
Georg Brandl48545522008-02-02 10:12:36 +00003886 class F(D):
3887 __metaclass__ = WorkOnce
Michael W. Hudson586da8f2002-11-27 15:20:19 +00003888
Georg Brandl48545522008-02-02 10:12:36 +00003889 class G(D):
3890 __metaclass__ = WorkAlways
Michael W. Hudson586da8f2002-11-27 15:20:19 +00003891
Georg Brandl48545522008-02-02 10:12:36 +00003892 # Immediate subclasses have their mro's adjusted in alphabetical
3893 # order, so E's will get adjusted before adjusting F's fails. We
3894 # check here that E's gets restored.
Michael W. Hudson586da8f2002-11-27 15:20:19 +00003895
Georg Brandl48545522008-02-02 10:12:36 +00003896 E_mro_before = E.__mro__
3897 D_mro_before = D.__mro__
Armin Rigofd163f92005-12-29 15:59:19 +00003898
Armin Rigofd163f92005-12-29 15:59:19 +00003899 try:
Georg Brandl48545522008-02-02 10:12:36 +00003900 D.__bases__ = (C2,)
3901 except RuntimeError:
3902 self.assertEqual(E.__mro__, E_mro_before)
3903 self.assertEqual(D.__mro__, D_mro_before)
3904 else:
3905 self.fail("exception not propagated")
3906
3907 def test_mutable_bases_catch_mro_conflict(self):
3908 # Testing mutable bases catch mro conflict...
3909 class A(object):
3910 pass
3911
3912 class B(object):
3913 pass
3914
3915 class C(A, B):
3916 pass
3917
3918 class D(A, B):
3919 pass
3920
3921 class E(C, D):
3922 pass
3923
3924 try:
3925 C.__bases__ = (B, A)
Armin Rigofd163f92005-12-29 15:59:19 +00003926 except TypeError:
3927 pass
3928 else:
Georg Brandl48545522008-02-02 10:12:36 +00003929 self.fail("didn't catch MRO conflict")
Armin Rigofd163f92005-12-29 15:59:19 +00003930
Georg Brandl48545522008-02-02 10:12:36 +00003931 def test_mutable_names(self):
3932 # Testing mutable names...
3933 class C(object):
3934 pass
3935
3936 # C.__module__ could be 'test_descr' or '__main__'
3937 mod = C.__module__
3938
3939 C.__name__ = 'D'
3940 self.assertEqual((C.__module__, C.__name__), (mod, 'D'))
3941
3942 C.__name__ = 'D.E'
3943 self.assertEqual((C.__module__, C.__name__), (mod, 'D.E'))
3944
3945 def test_subclass_right_op(self):
3946 # Testing correct dispatch of subclass overloading __r<op>__...
3947
3948 # This code tests various cases where right-dispatch of a subclass
3949 # should be preferred over left-dispatch of a base class.
3950
3951 # Case 1: subclass of int; this tests code in abstract.c::binary_op1()
3952
3953 class B(int):
3954 def __floordiv__(self, other):
3955 return "B.__floordiv__"
3956 def __rfloordiv__(self, other):
3957 return "B.__rfloordiv__"
3958
3959 self.assertEqual(B(1) // 1, "B.__floordiv__")
3960 self.assertEqual(1 // B(1), "B.__rfloordiv__")
3961
3962 # Case 2: subclass of object; this is just the baseline for case 3
3963
3964 class C(object):
3965 def __floordiv__(self, other):
3966 return "C.__floordiv__"
3967 def __rfloordiv__(self, other):
3968 return "C.__rfloordiv__"
3969
3970 self.assertEqual(C() // 1, "C.__floordiv__")
3971 self.assertEqual(1 // C(), "C.__rfloordiv__")
3972
3973 # Case 3: subclass of new-style class; here it gets interesting
3974
3975 class D(C):
3976 def __floordiv__(self, other):
3977 return "D.__floordiv__"
3978 def __rfloordiv__(self, other):
3979 return "D.__rfloordiv__"
3980
3981 self.assertEqual(D() // C(), "D.__floordiv__")
3982 self.assertEqual(C() // D(), "D.__rfloordiv__")
3983
3984 # Case 4: this didn't work right in 2.2.2 and 2.3a1
3985
3986 class E(C):
3987 pass
3988
3989 self.assertEqual(E.__rfloordiv__, C.__rfloordiv__)
3990
3991 self.assertEqual(E() // 1, "C.__floordiv__")
3992 self.assertEqual(1 // E(), "C.__rfloordiv__")
3993 self.assertEqual(E() // C(), "C.__floordiv__")
3994 self.assertEqual(C() // E(), "C.__floordiv__") # This one would fail
3995
3996 def test_meth_class_get(self):
3997 # Testing __get__ method of METH_CLASS C methods...
3998 # Full coverage of descrobject.c::classmethod_get()
3999
4000 # Baseline
4001 arg = [1, 2, 3]
4002 res = {1: None, 2: None, 3: None}
4003 self.assertEqual(dict.fromkeys(arg), res)
4004 self.assertEqual({}.fromkeys(arg), res)
4005
4006 # Now get the descriptor
4007 descr = dict.__dict__["fromkeys"]
4008
4009 # More baseline using the descriptor directly
4010 self.assertEqual(descr.__get__(None, dict)(arg), res)
4011 self.assertEqual(descr.__get__({})(arg), res)
4012
4013 # Now check various error cases
4014 try:
4015 descr.__get__(None, None)
4016 except TypeError:
4017 pass
4018 else:
4019 self.fail("shouldn't have allowed descr.__get__(None, None)")
4020 try:
4021 descr.__get__(42)
4022 except TypeError:
4023 pass
4024 else:
4025 self.fail("shouldn't have allowed descr.__get__(42)")
4026 try:
4027 descr.__get__(None, 42)
4028 except TypeError:
4029 pass
4030 else:
4031 self.fail("shouldn't have allowed descr.__get__(None, 42)")
4032 try:
4033 descr.__get__(None, int)
4034 except TypeError:
4035 pass
4036 else:
4037 self.fail("shouldn't have allowed descr.__get__(None, int)")
4038
4039 def test_isinst_isclass(self):
4040 # Testing proxy isinstance() and isclass()...
4041 class Proxy(object):
4042 def __init__(self, obj):
4043 self.__obj = obj
4044 def __getattribute__(self, name):
4045 if name.startswith("_Proxy__"):
4046 return object.__getattribute__(self, name)
4047 else:
4048 return getattr(self.__obj, name)
4049 # Test with a classic class
4050 class C:
4051 pass
4052 a = C()
4053 pa = Proxy(a)
4054 self.assert_(isinstance(a, C)) # Baseline
4055 self.assert_(isinstance(pa, C)) # Test
4056 # Test with a classic subclass
4057 class D(C):
4058 pass
4059 a = D()
4060 pa = Proxy(a)
4061 self.assert_(isinstance(a, C)) # Baseline
4062 self.assert_(isinstance(pa, C)) # Test
4063 # Test with a new-style class
4064 class C(object):
4065 pass
4066 a = C()
4067 pa = Proxy(a)
4068 self.assert_(isinstance(a, C)) # Baseline
4069 self.assert_(isinstance(pa, C)) # Test
4070 # Test with a new-style subclass
4071 class D(C):
4072 pass
4073 a = D()
4074 pa = Proxy(a)
4075 self.assert_(isinstance(a, C)) # Baseline
4076 self.assert_(isinstance(pa, C)) # Test
4077
4078 def test_proxy_super(self):
4079 # Testing super() for a proxy object...
4080 class Proxy(object):
4081 def __init__(self, obj):
4082 self.__obj = obj
4083 def __getattribute__(self, name):
4084 if name.startswith("_Proxy__"):
4085 return object.__getattribute__(self, name)
4086 else:
4087 return getattr(self.__obj, name)
4088
4089 class B(object):
4090 def f(self):
4091 return "B.f"
4092
4093 class C(B):
4094 def f(self):
4095 return super(C, self).f() + "->C.f"
4096
4097 obj = C()
4098 p = Proxy(obj)
4099 self.assertEqual(C.__dict__["f"](p), "B.f->C.f")
4100
4101 def test_carloverre(self):
4102 # Testing prohibition of Carlo Verre's hack...
4103 try:
4104 object.__setattr__(str, "foo", 42)
4105 except TypeError:
4106 pass
4107 else:
4108 self.fail("Carlo Verre __setattr__ suceeded!")
4109 try:
4110 object.__delattr__(str, "lower")
4111 except TypeError:
4112 pass
4113 else:
4114 self.fail("Carlo Verre __delattr__ succeeded!")
4115
4116 def test_weakref_segfault(self):
4117 # Testing weakref segfault...
4118 # SF 742911
4119 import weakref
4120
4121 class Provoker:
4122 def __init__(self, referrent):
4123 self.ref = weakref.ref(referrent)
4124
4125 def __del__(self):
4126 x = self.ref()
4127
4128 class Oops(object):
4129 pass
4130
4131 o = Oops()
4132 o.whatever = Provoker(o)
4133 del o
4134
4135 def test_wrapper_segfault(self):
4136 # SF 927248: deeply nested wrappers could cause stack overflow
4137 f = lambda:None
4138 for i in xrange(1000000):
4139 f = f.__call__
4140 f = None
4141
4142 def test_file_fault(self):
4143 # Testing sys.stdout is changed in getattr...
4144 import sys
4145 class StdoutGuard:
4146 def __getattr__(self, attr):
4147 sys.stdout = sys.__stdout__
4148 raise RuntimeError("Premature access to sys.stdout.%s" % attr)
4149 sys.stdout = StdoutGuard()
4150 try:
4151 print "Oops!"
4152 except RuntimeError:
4153 pass
4154
4155 def test_vicious_descriptor_nonsense(self):
4156 # Testing vicious_descriptor_nonsense...
4157
4158 # A potential segfault spotted by Thomas Wouters in mail to
4159 # python-dev 2003-04-17, turned into an example & fixed by Michael
4160 # Hudson just less than four months later...
4161
4162 class Evil(object):
4163 def __hash__(self):
4164 return hash('attr')
4165 def __eq__(self, other):
4166 del C.attr
4167 return 0
4168
4169 class Descr(object):
4170 def __get__(self, ob, type=None):
4171 return 1
4172
4173 class C(object):
4174 attr = Descr()
4175
4176 c = C()
4177 c.__dict__[Evil()] = 0
4178
4179 self.assertEqual(c.attr, 1)
4180 # this makes a crash more likely:
4181 import gc; gc.collect()
4182 self.assertEqual(hasattr(c, 'attr'), False)
4183
4184 def test_init(self):
4185 # SF 1155938
4186 class Foo(object):
4187 def __init__(self):
4188 return 10
4189 try:
4190 Foo()
4191 except TypeError:
4192 pass
4193 else:
4194 self.fail("did not test __init__() for None return")
4195
4196 def test_method_wrapper(self):
4197 # Testing method-wrapper objects...
4198 # <type 'method-wrapper'> did not support any reflection before 2.5
4199
4200 l = []
4201 self.assertEqual(l.__add__, l.__add__)
4202 self.assertEqual(l.__add__, [].__add__)
4203 self.assert_(l.__add__ != [5].__add__)
4204 self.assert_(l.__add__ != l.__mul__)
4205 self.assert_(l.__add__.__name__ == '__add__')
4206 self.assert_(l.__add__.__self__ is l)
4207 self.assert_(l.__add__.__objclass__ is list)
4208 self.assertEqual(l.__add__.__doc__, list.__add__.__doc__)
4209 try:
4210 hash(l.__add__)
4211 except TypeError:
4212 pass
4213 else:
4214 self.fail("no TypeError from hash([].__add__)")
4215
4216 t = ()
4217 t += (7,)
4218 self.assertEqual(t.__add__, (7,).__add__)
4219 self.assertEqual(hash(t.__add__), hash((7,).__add__))
4220
4221 def test_not_implemented(self):
4222 # Testing NotImplemented...
4223 # all binary methods should be able to return a NotImplemented
4224 import sys
4225 import types
4226 import operator
4227
4228 def specialmethod(self, other):
4229 return NotImplemented
4230
4231 def check(expr, x, y):
4232 try:
4233 exec expr in {'x': x, 'y': y, 'operator': operator}
4234 except TypeError:
4235 pass
Armin Rigofd163f92005-12-29 15:59:19 +00004236 else:
Georg Brandl48545522008-02-02 10:12:36 +00004237 self.fail("no TypeError from %r" % (expr,))
Armin Rigofd163f92005-12-29 15:59:19 +00004238
Georg Brandl48545522008-02-02 10:12:36 +00004239 N1 = sys.maxint + 1L # might trigger OverflowErrors instead of
4240 # TypeErrors
4241 N2 = sys.maxint # if sizeof(int) < sizeof(long), might trigger
4242 # ValueErrors instead of TypeErrors
4243 for metaclass in [type, types.ClassType]:
4244 for name, expr, iexpr in [
4245 ('__add__', 'x + y', 'x += y'),
4246 ('__sub__', 'x - y', 'x -= y'),
4247 ('__mul__', 'x * y', 'x *= y'),
4248 ('__truediv__', 'operator.truediv(x, y)', None),
4249 ('__floordiv__', 'operator.floordiv(x, y)', None),
4250 ('__div__', 'x / y', 'x /= y'),
4251 ('__mod__', 'x % y', 'x %= y'),
4252 ('__divmod__', 'divmod(x, y)', None),
4253 ('__pow__', 'x ** y', 'x **= y'),
4254 ('__lshift__', 'x << y', 'x <<= y'),
4255 ('__rshift__', 'x >> y', 'x >>= y'),
4256 ('__and__', 'x & y', 'x &= y'),
4257 ('__or__', 'x | y', 'x |= y'),
4258 ('__xor__', 'x ^ y', 'x ^= y'),
4259 ('__coerce__', 'coerce(x, y)', None)]:
4260 if name == '__coerce__':
4261 rname = name
4262 else:
4263 rname = '__r' + name[2:]
4264 A = metaclass('A', (), {name: specialmethod})
4265 B = metaclass('B', (), {rname: specialmethod})
4266 a = A()
4267 b = B()
4268 check(expr, a, a)
4269 check(expr, a, b)
4270 check(expr, b, a)
4271 check(expr, b, b)
4272 check(expr, a, N1)
4273 check(expr, a, N2)
4274 check(expr, N1, b)
4275 check(expr, N2, b)
4276 if iexpr:
4277 check(iexpr, a, a)
4278 check(iexpr, a, b)
4279 check(iexpr, b, a)
4280 check(iexpr, b, b)
4281 check(iexpr, a, N1)
4282 check(iexpr, a, N2)
4283 iname = '__i' + name[2:]
4284 C = metaclass('C', (), {iname: specialmethod})
4285 c = C()
4286 check(iexpr, c, a)
4287 check(iexpr, c, b)
4288 check(iexpr, c, N1)
4289 check(iexpr, c, N2)
Georg Brandl0fca97a2007-03-05 22:28:08 +00004290
Georg Brandl48545522008-02-02 10:12:36 +00004291 def test_assign_slice(self):
4292 # ceval.c's assign_slice used to check for
4293 # tp->tp_as_sequence->sq_slice instead of
4294 # tp->tp_as_sequence->sq_ass_slice
Georg Brandl0fca97a2007-03-05 22:28:08 +00004295
Georg Brandl48545522008-02-02 10:12:36 +00004296 class C(object):
4297 def __setslice__(self, start, stop, value):
4298 self.value = value
Georg Brandl0fca97a2007-03-05 22:28:08 +00004299
Georg Brandl48545522008-02-02 10:12:36 +00004300 c = C()
4301 c[1:2] = 3
4302 self.assertEqual(c.value, 3)
Guido van Rossum9acc3872008-01-23 23:23:43 +00004303
Benjamin Peterson9adae2e2008-11-17 22:44:30 +00004304 def test_getattr_hooks(self):
4305 # issue 4230
4306
4307 class Descriptor(object):
4308 counter = 0
4309 def __get__(self, obj, objtype=None):
4310 def getter(name):
4311 self.counter += 1
4312 raise AttributeError(name)
4313 return getter
4314
4315 descr = Descriptor()
4316 class A(object):
4317 __getattribute__ = descr
4318 class B(object):
4319 __getattr__ = descr
4320 class C(object):
4321 __getattribute__ = descr
4322 __getattr__ = descr
4323
4324 self.assertRaises(AttributeError, getattr, A(), "attr")
4325 self.assertEquals(descr.counter, 1)
4326 self.assertRaises(AttributeError, getattr, B(), "attr")
4327 self.assertEquals(descr.counter, 2)
4328 self.assertRaises(AttributeError, getattr, C(), "attr")
4329 self.assertEquals(descr.counter, 4)
4330
4331 import gc
4332 class EvilGetattribute(object):
4333 # This used to segfault
4334 def __getattr__(self, name):
4335 raise AttributeError(name)
4336 def __getattribute__(self, name):
4337 del EvilGetattribute.__getattr__
4338 for i in range(5):
4339 gc.collect()
4340 raise AttributeError(name)
4341
4342 self.assertRaises(AttributeError, getattr, EvilGetattribute(), "attr")
4343
Guido van Rossum9acc3872008-01-23 23:23:43 +00004344
Georg Brandl48545522008-02-02 10:12:36 +00004345class DictProxyTests(unittest.TestCase):
4346 def setUp(self):
4347 class C(object):
4348 def meth(self):
4349 pass
4350 self.C = C
Guido van Rossum9acc3872008-01-23 23:23:43 +00004351
Georg Brandl48545522008-02-02 10:12:36 +00004352 def test_iter_keys(self):
4353 # Testing dict-proxy iterkeys...
4354 keys = [ key for key in self.C.__dict__.iterkeys() ]
4355 keys.sort()
4356 self.assertEquals(keys, ['__dict__', '__doc__', '__module__',
4357 '__weakref__', 'meth'])
Guido van Rossum9acc3872008-01-23 23:23:43 +00004358
Georg Brandl48545522008-02-02 10:12:36 +00004359 def test_iter_values(self):
4360 # Testing dict-proxy itervalues...
4361 values = [ values for values in self.C.__dict__.itervalues() ]
4362 self.assertEqual(len(values), 5)
Guido van Rossum9acc3872008-01-23 23:23:43 +00004363
Georg Brandl48545522008-02-02 10:12:36 +00004364 def test_iter_items(self):
4365 # Testing dict-proxy iteritems...
4366 keys = [ key for (key, value) in self.C.__dict__.iteritems() ]
4367 keys.sort()
4368 self.assertEqual(keys, ['__dict__', '__doc__', '__module__',
4369 '__weakref__', 'meth'])
Guido van Rossum9acc3872008-01-23 23:23:43 +00004370
Georg Brandl48545522008-02-02 10:12:36 +00004371 def test_dict_type_with_metaclass(self):
4372 # Testing type of __dict__ when __metaclass__ set...
4373 class B(object):
4374 pass
4375 class M(type):
4376 pass
4377 class C:
4378 # In 2.3a1, C.__dict__ was a real dict rather than a dict proxy
4379 __metaclass__ = M
4380 self.assertEqual(type(C.__dict__), type(B.__dict__))
Guido van Rossum9acc3872008-01-23 23:23:43 +00004381
Guido van Rossum9acc3872008-01-23 23:23:43 +00004382
Georg Brandl48545522008-02-02 10:12:36 +00004383class PTypesLongInitTest(unittest.TestCase):
4384 # This is in its own TestCase so that it can be run before any other tests.
4385 def test_pytype_long_ready(self):
4386 # Testing SF bug 551412 ...
Guido van Rossum9acc3872008-01-23 23:23:43 +00004387
Georg Brandl48545522008-02-02 10:12:36 +00004388 # This dumps core when SF bug 551412 isn't fixed --
4389 # but only when test_descr.py is run separately.
4390 # (That can't be helped -- as soon as PyType_Ready()
4391 # is called for PyLong_Type, the bug is gone.)
4392 class UserLong(object):
4393 def __pow__(self, *args):
4394 pass
4395 try:
4396 pow(0L, UserLong(), 0L)
4397 except:
4398 pass
Guido van Rossum9acc3872008-01-23 23:23:43 +00004399
Georg Brandl48545522008-02-02 10:12:36 +00004400 # Another segfault only when run early
4401 # (before PyType_Ready(tuple) is called)
4402 type.mro(tuple)
Guido van Rossum37edeab2008-01-24 17:58:05 +00004403
4404
Guido van Rossuma56b42b2001-09-20 21:39:07 +00004405def test_main():
Georg Brandl48545522008-02-02 10:12:36 +00004406 # Run all local test cases, with PTypesLongInitTest first.
4407 test_support.run_unittest(PTypesLongInitTest, OperatorsTest,
4408 ClassPropertiesAndMethods, DictProxyTests)
Tim Peters6d6c1a32001-08-02 04:15:00 +00004409
Guido van Rossuma56b42b2001-09-20 21:39:07 +00004410if __name__ == "__main__":
4411 test_main()