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