blob: 755a967f45d593568930605e73523959fbc07626 [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
1185 def test_dynamics(self):
1186 # Testing class attribute propagation...
1187 class D(object):
1188 pass
1189 class E(D):
1190 pass
1191 class F(D):
1192 pass
1193 D.foo = 1
1194 self.assertEqual(D.foo, 1)
1195 # Test that dynamic attributes are inherited
1196 self.assertEqual(E.foo, 1)
1197 self.assertEqual(F.foo, 1)
1198 # Test dynamic instances
1199 class C(object):
1200 pass
1201 a = C()
1202 self.assertFalse(hasattr(a, "foobar"))
1203 C.foobar = 2
1204 self.assertEqual(a.foobar, 2)
1205 C.method = lambda self: 42
1206 self.assertEqual(a.method(), 42)
1207 C.__repr__ = lambda self: "C()"
1208 self.assertEqual(repr(a), "C()")
1209 C.__int__ = lambda self: 100
1210 self.assertEqual(int(a), 100)
1211 self.assertEqual(a.foobar, 2)
1212 self.assertFalse(hasattr(a, "spam"))
1213 def mygetattr(self, name):
1214 if name == "spam":
1215 return "spam"
1216 raise AttributeError
1217 C.__getattr__ = mygetattr
1218 self.assertEqual(a.spam, "spam")
1219 a.new = 12
1220 self.assertEqual(a.new, 12)
1221 def mysetattr(self, name, value):
1222 if name == "spam":
1223 raise AttributeError
1224 return object.__setattr__(self, name, value)
1225 C.__setattr__ = mysetattr
1226 try:
1227 a.spam = "not spam"
1228 except AttributeError:
1229 pass
1230 else:
1231 self.fail("expected AttributeError")
1232 self.assertEqual(a.spam, "spam")
1233 class D(C):
1234 pass
1235 d = D()
1236 d.foo = 1
1237 self.assertEqual(d.foo, 1)
1238
1239 # Test handling of int*seq and seq*int
1240 class I(int):
1241 pass
1242 self.assertEqual("a"*I(2), "aa")
1243 self.assertEqual(I(2)*"a", "aa")
1244 self.assertEqual(2*I(3), 6)
1245 self.assertEqual(I(3)*2, 6)
1246 self.assertEqual(I(3)*I(2), 6)
1247
1248 # Test handling of long*seq and seq*long
1249 class L(long):
1250 pass
1251 self.assertEqual("a"*L(2L), "aa")
1252 self.assertEqual(L(2L)*"a", "aa")
1253 self.assertEqual(2*L(3), 6)
1254 self.assertEqual(L(3)*2, 6)
1255 self.assertEqual(L(3)*L(2), 6)
1256
1257 # Test comparison of classes with dynamic metaclasses
1258 class dynamicmetaclass(type):
1259 pass
1260 class someclass:
1261 __metaclass__ = dynamicmetaclass
1262 self.assertNotEqual(someclass, object)
1263
1264 def test_errors(self):
1265 # Testing errors...
1266 try:
1267 class C(list, dict):
1268 pass
1269 except TypeError:
1270 pass
1271 else:
1272 self.fail("inheritance from both list and dict should be illegal")
1273
1274 try:
1275 class C(object, None):
1276 pass
1277 except TypeError:
1278 pass
1279 else:
1280 self.fail("inheritance from non-type should be illegal")
1281 class Classic:
1282 pass
1283
1284 try:
1285 class C(type(len)):
1286 pass
1287 except TypeError:
1288 pass
1289 else:
1290 self.fail("inheritance from CFunction should be illegal")
1291
1292 try:
1293 class C(object):
1294 __slots__ = 1
1295 except TypeError:
1296 pass
1297 else:
1298 self.fail("__slots__ = 1 should be illegal")
1299
1300 try:
1301 class C(object):
1302 __slots__ = [1]
1303 except TypeError:
1304 pass
1305 else:
1306 self.fail("__slots__ = [1] should be illegal")
1307
1308 class M1(type):
1309 pass
1310 class M2(type):
1311 pass
1312 class A1(object):
1313 __metaclass__ = M1
1314 class A2(object):
1315 __metaclass__ = M2
1316 try:
1317 class B(A1, A2):
1318 pass
1319 except TypeError:
1320 pass
1321 else:
1322 self.fail("finding the most derived metaclass should have failed")
1323
1324 def test_classmethods(self):
1325 # Testing class methods...
1326 class C(object):
1327 def foo(*a): return a
1328 goo = classmethod(foo)
1329 c = C()
1330 self.assertEqual(C.goo(1), (C, 1))
1331 self.assertEqual(c.goo(1), (C, 1))
1332 self.assertEqual(c.foo(1), (c, 1))
1333 class D(C):
1334 pass
1335 d = D()
1336 self.assertEqual(D.goo(1), (D, 1))
1337 self.assertEqual(d.goo(1), (D, 1))
1338 self.assertEqual(d.foo(1), (d, 1))
1339 self.assertEqual(D.foo(d, 1), (d, 1))
1340 # Test for a specific crash (SF bug 528132)
1341 def f(cls, arg): return (cls, arg)
1342 ff = classmethod(f)
1343 self.assertEqual(ff.__get__(0, int)(42), (int, 42))
1344 self.assertEqual(ff.__get__(0)(42), (int, 42))
1345
1346 # Test super() with classmethods (SF bug 535444)
1347 self.assertEqual(C.goo.im_self, C)
1348 self.assertEqual(D.goo.im_self, D)
1349 self.assertEqual(super(D,D).goo.im_self, D)
1350 self.assertEqual(super(D,d).goo.im_self, D)
1351 self.assertEqual(super(D,D).goo(), (D,))
1352 self.assertEqual(super(D,d).goo(), (D,))
1353
1354 # Verify that argument is checked for callability (SF bug 753451)
1355 try:
1356 classmethod(1).__get__(1)
1357 except TypeError:
1358 pass
1359 else:
1360 self.fail("classmethod should check for callability")
1361
1362 # Verify that classmethod() doesn't allow keyword args
1363 try:
1364 classmethod(f, kw=1)
1365 except TypeError:
1366 pass
1367 else:
1368 self.fail("classmethod shouldn't accept keyword args")
1369
1370 def test_classmethods_in_c(self):
1371 # Testing C-based class methods...
1372 import xxsubtype as spam
1373 a = (1, 2, 3)
1374 d = {'abc': 123}
1375 x, a1, d1 = spam.spamlist.classmeth(*a, **d)
1376 self.assertEqual(x, spam.spamlist)
1377 self.assertEqual(a, a1)
1378 self.assertEqual(d, d1)
1379 x, a1, d1 = spam.spamlist().classmeth(*a, **d)
1380 self.assertEqual(x, spam.spamlist)
1381 self.assertEqual(a, a1)
1382 self.assertEqual(d, d1)
1383
1384 def test_staticmethods(self):
1385 # Testing static methods...
1386 class C(object):
1387 def foo(*a): return a
1388 goo = staticmethod(foo)
1389 c = C()
1390 self.assertEqual(C.goo(1), (1,))
1391 self.assertEqual(c.goo(1), (1,))
1392 self.assertEqual(c.foo(1), (c, 1,))
1393 class D(C):
1394 pass
1395 d = D()
1396 self.assertEqual(D.goo(1), (1,))
1397 self.assertEqual(d.goo(1), (1,))
1398 self.assertEqual(d.foo(1), (d, 1))
1399 self.assertEqual(D.foo(d, 1), (d, 1))
1400
1401 def test_staticmethods_in_c(self):
1402 # Testing C-based static methods...
1403 import xxsubtype as spam
1404 a = (1, 2, 3)
1405 d = {"abc": 123}
1406 x, a1, d1 = spam.spamlist.staticmeth(*a, **d)
1407 self.assertEqual(x, None)
1408 self.assertEqual(a, a1)
1409 self.assertEqual(d, d1)
1410 x, a1, d2 = spam.spamlist().staticmeth(*a, **d)
1411 self.assertEqual(x, None)
1412 self.assertEqual(a, a1)
1413 self.assertEqual(d, d1)
1414
1415 def test_classic(self):
1416 # Testing classic classes...
1417 class C:
1418 def foo(*a): return a
1419 goo = classmethod(foo)
1420 c = C()
1421 self.assertEqual(C.goo(1), (C, 1))
1422 self.assertEqual(c.goo(1), (C, 1))
1423 self.assertEqual(c.foo(1), (c, 1))
1424 class D(C):
1425 pass
1426 d = D()
1427 self.assertEqual(D.goo(1), (D, 1))
1428 self.assertEqual(d.goo(1), (D, 1))
1429 self.assertEqual(d.foo(1), (d, 1))
1430 self.assertEqual(D.foo(d, 1), (d, 1))
1431 class E: # *not* subclassing from C
1432 foo = C.foo
1433 self.assertEqual(E().foo, C.foo) # i.e., unbound
1434 self.assert_(repr(C.foo.__get__(C())).startswith("<bound method "))
1435
1436 def test_compattr(self):
1437 # Testing computed attributes...
1438 class C(object):
1439 class computed_attribute(object):
1440 def __init__(self, get, set=None, delete=None):
1441 self.__get = get
1442 self.__set = set
1443 self.__delete = delete
1444 def __get__(self, obj, type=None):
1445 return self.__get(obj)
1446 def __set__(self, obj, value):
1447 return self.__set(obj, value)
1448 def __delete__(self, obj):
1449 return self.__delete(obj)
1450 def __init__(self):
1451 self.__x = 0
1452 def __get_x(self):
1453 x = self.__x
1454 self.__x = x+1
1455 return x
1456 def __set_x(self, x):
1457 self.__x = x
1458 def __delete_x(self):
1459 del self.__x
1460 x = computed_attribute(__get_x, __set_x, __delete_x)
1461 a = C()
1462 self.assertEqual(a.x, 0)
1463 self.assertEqual(a.x, 1)
1464 a.x = 10
1465 self.assertEqual(a.x, 10)
1466 self.assertEqual(a.x, 11)
1467 del a.x
1468 self.assertEqual(hasattr(a, 'x'), 0)
1469
1470 def test_newslots(self):
1471 # Testing __new__ slot override...
1472 class C(list):
1473 def __new__(cls):
1474 self = list.__new__(cls)
1475 self.foo = 1
1476 return self
1477 def __init__(self):
1478 self.foo = self.foo + 2
1479 a = C()
1480 self.assertEqual(a.foo, 3)
1481 self.assertEqual(a.__class__, C)
1482 class D(C):
1483 pass
1484 b = D()
1485 self.assertEqual(b.foo, 3)
1486 self.assertEqual(b.__class__, D)
1487
1488 def test_altmro(self):
1489 # Testing mro() and overriding it...
1490 class A(object):
1491 def f(self): return "A"
1492 class B(A):
1493 pass
1494 class C(A):
1495 def f(self): return "C"
1496 class D(B, C):
1497 pass
1498 self.assertEqual(D.mro(), [D, B, C, A, object])
1499 self.assertEqual(D.__mro__, (D, B, C, A, object))
1500 self.assertEqual(D().f(), "C")
1501
1502 class PerverseMetaType(type):
1503 def mro(cls):
1504 L = type.mro(cls)
1505 L.reverse()
1506 return L
1507 class X(D,B,C,A):
1508 __metaclass__ = PerverseMetaType
1509 self.assertEqual(X.__mro__, (object, A, C, B, D, X))
1510 self.assertEqual(X().f(), "A")
1511
1512 try:
1513 class X(object):
1514 class __metaclass__(type):
1515 def mro(self):
1516 return [self, dict, object]
1517 except TypeError:
1518 pass
1519 else:
1520 self.fail("devious mro() return not caught")
1521
1522 try:
1523 class X(object):
1524 class __metaclass__(type):
1525 def mro(self):
1526 return [1]
1527 except TypeError:
1528 pass
1529 else:
1530 self.fail("non-class mro() return not caught")
1531
1532 try:
1533 class X(object):
1534 class __metaclass__(type):
1535 def mro(self):
1536 return 1
1537 except TypeError:
1538 pass
1539 else:
1540 self.fail("non-sequence mro() return not caught")
1541
1542 def test_overloading(self):
1543 # Testing operator overloading...
1544
1545 class B(object):
1546 "Intermediate class because object doesn't have a __setattr__"
1547
1548 class C(B):
1549 def __getattr__(self, name):
1550 if name == "foo":
1551 return ("getattr", name)
1552 else:
1553 raise AttributeError
1554 def __setattr__(self, name, value):
1555 if name == "foo":
1556 self.setattr = (name, value)
1557 else:
1558 return B.__setattr__(self, name, value)
1559 def __delattr__(self, name):
1560 if name == "foo":
1561 self.delattr = name
1562 else:
1563 return B.__delattr__(self, name)
1564
1565 def __getitem__(self, key):
1566 return ("getitem", key)
1567 def __setitem__(self, key, value):
1568 self.setitem = (key, value)
1569 def __delitem__(self, key):
1570 self.delitem = key
1571
1572 def __getslice__(self, i, j):
1573 return ("getslice", i, j)
1574 def __setslice__(self, i, j, value):
1575 self.setslice = (i, j, value)
1576 def __delslice__(self, i, j):
1577 self.delslice = (i, j)
1578
1579 a = C()
1580 self.assertEqual(a.foo, ("getattr", "foo"))
1581 a.foo = 12
1582 self.assertEqual(a.setattr, ("foo", 12))
1583 del a.foo
1584 self.assertEqual(a.delattr, "foo")
1585
1586 self.assertEqual(a[12], ("getitem", 12))
1587 a[12] = 21
1588 self.assertEqual(a.setitem, (12, 21))
1589 del a[12]
1590 self.assertEqual(a.delitem, 12)
1591
1592 self.assertEqual(a[0:10], ("getslice", 0, 10))
1593 a[0:10] = "foo"
1594 self.assertEqual(a.setslice, (0, 10, "foo"))
1595 del a[0:10]
1596 self.assertEqual(a.delslice, (0, 10))
1597
1598 def test_methods(self):
1599 # Testing methods...
1600 class C(object):
1601 def __init__(self, x):
1602 self.x = x
1603 def foo(self):
1604 return self.x
1605 c1 = C(1)
1606 self.assertEqual(c1.foo(), 1)
1607 class D(C):
1608 boo = C.foo
1609 goo = c1.foo
1610 d2 = D(2)
1611 self.assertEqual(d2.foo(), 2)
1612 self.assertEqual(d2.boo(), 2)
1613 self.assertEqual(d2.goo(), 1)
1614 class E(object):
1615 foo = C.foo
1616 self.assertEqual(E().foo, C.foo) # i.e., unbound
1617 self.assert_(repr(C.foo.__get__(C(1))).startswith("<bound method "))
1618
1619 def test_specials(self):
1620 # Testing special operators...
1621 # Test operators like __hash__ for which a built-in default exists
1622
1623 # Test the default behavior for static classes
1624 class C(object):
1625 def __getitem__(self, i):
1626 if 0 <= i < 10: return i
1627 raise IndexError
1628 c1 = C()
1629 c2 = C()
1630 self.assert_(not not c1) # What?
1631 self.assertNotEqual(id(c1), id(c2))
1632 hash(c1)
1633 hash(c2)
1634 self.assertEqual(cmp(c1, c2), cmp(id(c1), id(c2)))
1635 self.assertEqual(c1, c1)
1636 self.assert_(c1 != c2)
1637 self.assert_(not c1 != c1)
1638 self.assert_(not c1 == c2)
1639 # Note that the module name appears in str/repr, and that varies
1640 # depending on whether this test is run standalone or from a framework.
1641 self.assert_(str(c1).find('C object at ') >= 0)
1642 self.assertEqual(str(c1), repr(c1))
1643 self.assert_(-1 not in c1)
1644 for i in range(10):
1645 self.assert_(i in c1)
1646 self.assertFalse(10 in c1)
1647 # Test the default behavior for dynamic classes
1648 class D(object):
1649 def __getitem__(self, i):
1650 if 0 <= i < 10: return i
1651 raise IndexError
1652 d1 = D()
1653 d2 = D()
1654 self.assert_(not not d1)
1655 self.assertNotEqual(id(d1), id(d2))
1656 hash(d1)
1657 hash(d2)
1658 self.assertEqual(cmp(d1, d2), cmp(id(d1), id(d2)))
1659 self.assertEqual(d1, d1)
1660 self.assertNotEqual(d1, d2)
1661 self.assert_(not d1 != d1)
1662 self.assert_(not d1 == d2)
1663 # Note that the module name appears in str/repr, and that varies
1664 # depending on whether this test is run standalone or from a framework.
1665 self.assert_(str(d1).find('D object at ') >= 0)
1666 self.assertEqual(str(d1), repr(d1))
1667 self.assert_(-1 not in d1)
1668 for i in range(10):
1669 self.assert_(i in d1)
1670 self.assertFalse(10 in d1)
1671 # Test overridden behavior for static classes
1672 class Proxy(object):
1673 def __init__(self, x):
1674 self.x = x
1675 def __nonzero__(self):
1676 return not not self.x
1677 def __hash__(self):
1678 return hash(self.x)
1679 def __eq__(self, other):
1680 return self.x == other
1681 def __ne__(self, other):
1682 return self.x != other
1683 def __cmp__(self, other):
1684 return cmp(self.x, other.x)
1685 def __str__(self):
1686 return "Proxy:%s" % self.x
1687 def __repr__(self):
1688 return "Proxy(%r)" % self.x
1689 def __contains__(self, value):
1690 return value in self.x
1691 p0 = Proxy(0)
1692 p1 = Proxy(1)
1693 p_1 = Proxy(-1)
1694 self.assertFalse(p0)
1695 self.assert_(not not p1)
1696 self.assertEqual(hash(p0), hash(0))
1697 self.assertEqual(p0, p0)
1698 self.assertNotEqual(p0, p1)
1699 self.assert_(not p0 != p0)
1700 self.assertEqual(not p0, p1)
1701 self.assertEqual(cmp(p0, p1), -1)
1702 self.assertEqual(cmp(p0, p0), 0)
1703 self.assertEqual(cmp(p0, p_1), 1)
1704 self.assertEqual(str(p0), "Proxy:0")
1705 self.assertEqual(repr(p0), "Proxy(0)")
1706 p10 = Proxy(range(10))
1707 self.assertFalse(-1 in p10)
1708 for i in range(10):
1709 self.assert_(i in p10)
1710 self.assertFalse(10 in p10)
1711 # Test overridden behavior for dynamic classes
1712 class DProxy(object):
1713 def __init__(self, x):
1714 self.x = x
1715 def __nonzero__(self):
1716 return not not self.x
1717 def __hash__(self):
1718 return hash(self.x)
1719 def __eq__(self, other):
1720 return self.x == other
1721 def __ne__(self, other):
1722 return self.x != other
1723 def __cmp__(self, other):
1724 return cmp(self.x, other.x)
1725 def __str__(self):
1726 return "DProxy:%s" % self.x
1727 def __repr__(self):
1728 return "DProxy(%r)" % self.x
1729 def __contains__(self, value):
1730 return value in self.x
1731 p0 = DProxy(0)
1732 p1 = DProxy(1)
1733 p_1 = DProxy(-1)
1734 self.assertFalse(p0)
1735 self.assert_(not not p1)
1736 self.assertEqual(hash(p0), hash(0))
1737 self.assertEqual(p0, p0)
1738 self.assertNotEqual(p0, p1)
1739 self.assertNotEqual(not p0, p0)
1740 self.assertEqual(not p0, p1)
1741 self.assertEqual(cmp(p0, p1), -1)
1742 self.assertEqual(cmp(p0, p0), 0)
1743 self.assertEqual(cmp(p0, p_1), 1)
1744 self.assertEqual(str(p0), "DProxy:0")
1745 self.assertEqual(repr(p0), "DProxy(0)")
1746 p10 = DProxy(range(10))
1747 self.assertFalse(-1 in p10)
1748 for i in range(10):
1749 self.assert_(i in p10)
1750 self.assertFalse(10 in p10)
1751
1752 # Safety test for __cmp__
1753 def unsafecmp(a, b):
1754 try:
1755 a.__class__.__cmp__(a, b)
1756 except TypeError:
1757 pass
Guido van Rossum4bb1e362001-09-28 23:49:48 +00001758 else:
Georg Brandl48545522008-02-02 10:12:36 +00001759 self.fail("shouldn't allow %s.__cmp__(%r, %r)" % (
1760 a.__class__, a, b))
1761
1762 unsafecmp(u"123", "123")
1763 unsafecmp("123", u"123")
1764 unsafecmp(1, 1.0)
1765 unsafecmp(1.0, 1)
1766 unsafecmp(1, 1L)
1767 unsafecmp(1L, 1)
1768
1769 def test_recursions(self):
1770 # Testing recursion checks ...
1771 class Letter(str):
1772 def __new__(cls, letter):
1773 if letter == 'EPS':
1774 return str.__new__(cls)
1775 return str.__new__(cls, letter)
1776 def __str__(self):
1777 if not self:
1778 return 'EPS'
1779 return self
1780 # sys.stdout needs to be the original to trigger the recursion bug
1781 import sys
1782 test_stdout = sys.stdout
1783 sys.stdout = test_support.get_original_stdout()
1784 try:
1785 # nothing should actually be printed, this should raise an exception
1786 print Letter('w')
1787 except RuntimeError:
1788 pass
1789 else:
1790 self.fail("expected a RuntimeError for print recursion")
1791 finally:
1792 sys.stdout = test_stdout
1793
1794 # Bug #1202533.
1795 class A(object):
1796 pass
1797 A.__mul__ = types.MethodType(lambda self, x: self * x, None, A)
1798 try:
1799 A()*2
1800 except RuntimeError:
1801 pass
1802 else:
1803 self.fail("expected a RuntimeError")
1804
1805 def test_weakrefs(self):
1806 # Testing weak references...
1807 import weakref
1808 class C(object):
1809 pass
1810 c = C()
1811 r = weakref.ref(c)
1812 self.assertEqual(r(), c)
1813 del c
1814 self.assertEqual(r(), None)
1815 del r
1816 class NoWeak(object):
1817 __slots__ = ['foo']
1818 no = NoWeak()
1819 try:
1820 weakref.ref(no)
1821 except TypeError, msg:
1822 self.assert_(str(msg).find("weak reference") >= 0)
1823 else:
1824 self.fail("weakref.ref(no) should be illegal")
1825 class Weak(object):
1826 __slots__ = ['foo', '__weakref__']
1827 yes = Weak()
1828 r = weakref.ref(yes)
1829 self.assertEqual(r(), yes)
1830 del yes
1831 self.assertEqual(r(), None)
1832 del r
1833
1834 def test_properties(self):
1835 # Testing property...
1836 class C(object):
1837 def getx(self):
1838 return self.__x
1839 def setx(self, value):
1840 self.__x = value
1841 def delx(self):
1842 del self.__x
1843 x = property(getx, setx, delx, doc="I'm the x property.")
1844 a = C()
1845 self.assertFalse(hasattr(a, "x"))
1846 a.x = 42
1847 self.assertEqual(a._C__x, 42)
1848 self.assertEqual(a.x, 42)
1849 del a.x
1850 self.assertFalse(hasattr(a, "x"))
1851 self.assertFalse(hasattr(a, "_C__x"))
1852 C.x.__set__(a, 100)
1853 self.assertEqual(C.x.__get__(a), 100)
1854 C.x.__delete__(a)
1855 self.assertFalse(hasattr(a, "x"))
1856
1857 raw = C.__dict__['x']
1858 self.assert_(isinstance(raw, property))
1859
1860 attrs = dir(raw)
1861 self.assert_("__doc__" in attrs)
1862 self.assert_("fget" in attrs)
1863 self.assert_("fset" in attrs)
1864 self.assert_("fdel" in attrs)
1865
1866 self.assertEqual(raw.__doc__, "I'm the x property.")
1867 self.assert_(raw.fget is C.__dict__['getx'])
1868 self.assert_(raw.fset is C.__dict__['setx'])
1869 self.assert_(raw.fdel is C.__dict__['delx'])
1870
1871 for attr in "__doc__", "fget", "fset", "fdel":
1872 try:
1873 setattr(raw, attr, 42)
1874 except TypeError, msg:
1875 if str(msg).find('readonly') < 0:
1876 self.fail("when setting readonly attr %r on a property, "
1877 "got unexpected TypeError msg %r" % (attr, str(msg)))
Guido van Rossum4bb1e362001-09-28 23:49:48 +00001878 else:
Georg Brandl48545522008-02-02 10:12:36 +00001879 self.fail("expected TypeError from trying to set readonly %r "
1880 "attr on a property" % attr)
Tim Peters2f93e282001-10-04 05:27:00 +00001881
Georg Brandl48545522008-02-02 10:12:36 +00001882 class D(object):
1883 __getitem__ = property(lambda s: 1/0)
Guido van Rossum4bb1e362001-09-28 23:49:48 +00001884
Georg Brandl48545522008-02-02 10:12:36 +00001885 d = D()
1886 try:
1887 for i in d:
1888 str(i)
1889 except ZeroDivisionError:
Walter Dörwalddbd2d252002-03-25 18:36:32 +00001890 pass
Georg Brandl48545522008-02-02 10:12:36 +00001891 else:
1892 self.fail("expected ZeroDivisionError from bad property")
Walter Dörwalddbd2d252002-03-25 18:36:32 +00001893
Georg Brandl48545522008-02-02 10:12:36 +00001894 class E(object):
1895 def getter(self):
1896 "getter method"
1897 return 0
1898 def setter(self_, value):
1899 "setter method"
1900 pass
1901 prop = property(getter)
1902 self.assertEqual(prop.__doc__, "getter method")
1903 prop2 = property(fset=setter)
1904 self.assertEqual(prop2.__doc__, None)
1905
1906 # this segfaulted in 2.5b2
1907 try:
1908 import _testcapi
1909 except ImportError:
Walter Dörwalddbd2d252002-03-25 18:36:32 +00001910 pass
Georg Brandl48545522008-02-02 10:12:36 +00001911 else:
1912 class X(object):
1913 p = property(_testcapi.test_with_docstring)
Walter Dörwalddbd2d252002-03-25 18:36:32 +00001914
Georg Brandl48545522008-02-02 10:12:36 +00001915 def test_properties_plus(self):
1916 class C(object):
1917 foo = property(doc="hello")
1918 @foo.getter
1919 def foo(self):
1920 return self._foo
1921 @foo.setter
1922 def foo(self, value):
1923 self._foo = abs(value)
1924 @foo.deleter
1925 def foo(self):
1926 del self._foo
1927 c = C()
1928 self.assertEqual(C.foo.__doc__, "hello")
1929 self.assertFalse(hasattr(c, "foo"))
1930 c.foo = -42
1931 self.assert_(hasattr(c, '_foo'))
1932 self.assertEqual(c._foo, 42)
1933 self.assertEqual(c.foo, 42)
1934 del c.foo
1935 self.assertFalse(hasattr(c, '_foo'))
1936 self.assertFalse(hasattr(c, "foo"))
Walter Dörwalddbd2d252002-03-25 18:36:32 +00001937
Georg Brandl48545522008-02-02 10:12:36 +00001938 class D(C):
1939 @C.foo.deleter
1940 def foo(self):
1941 try:
1942 del self._foo
1943 except AttributeError:
1944 pass
1945 d = D()
1946 d.foo = 24
1947 self.assertEqual(d.foo, 24)
1948 del d.foo
1949 del d.foo
Guido van Rossum8ace1ab2002-04-06 01:05:01 +00001950
Georg Brandl48545522008-02-02 10:12:36 +00001951 class E(object):
1952 @property
1953 def foo(self):
1954 return self._foo
1955 @foo.setter
1956 def foo(self, value):
1957 raise RuntimeError
1958 @foo.setter
1959 def foo(self, value):
1960 self._foo = abs(value)
1961 @foo.deleter
1962 def foo(self, value=None):
1963 del self._foo
Guido van Rossume8fc6402002-04-16 16:44:51 +00001964
Georg Brandl48545522008-02-02 10:12:36 +00001965 e = E()
1966 e.foo = -42
1967 self.assertEqual(e.foo, 42)
1968 del e.foo
Guido van Rossumd99b3e72002-04-18 00:27:33 +00001969
Georg Brandl48545522008-02-02 10:12:36 +00001970 class F(E):
1971 @E.foo.deleter
1972 def foo(self):
1973 del self._foo
1974 @foo.setter
1975 def foo(self, value):
1976 self._foo = max(0, value)
1977 f = F()
1978 f.foo = -10
1979 self.assertEqual(f.foo, 0)
1980 del f.foo
Guido van Rossuma48cb8f2002-06-06 17:53:03 +00001981
Georg Brandl48545522008-02-02 10:12:36 +00001982 def test_dict_constructors(self):
1983 # Testing dict constructor ...
1984 d = dict()
1985 self.assertEqual(d, {})
1986 d = dict({})
1987 self.assertEqual(d, {})
1988 d = dict({1: 2, 'a': 'b'})
1989 self.assertEqual(d, {1: 2, 'a': 'b'})
1990 self.assertEqual(d, dict(d.items()))
1991 self.assertEqual(d, dict(d.iteritems()))
1992 d = dict({'one':1, 'two':2})
1993 self.assertEqual(d, dict(one=1, two=2))
1994 self.assertEqual(d, dict(**d))
1995 self.assertEqual(d, dict({"one": 1}, two=2))
1996 self.assertEqual(d, dict([("two", 2)], one=1))
1997 self.assertEqual(d, dict([("one", 100), ("two", 200)], **d))
1998 self.assertEqual(d, dict(**d))
Guido van Rossum09638c12002-06-13 19:17:46 +00001999
Georg Brandl48545522008-02-02 10:12:36 +00002000 for badarg in 0, 0L, 0j, "0", [0], (0,):
2001 try:
2002 dict(badarg)
2003 except TypeError:
2004 pass
2005 except ValueError:
2006 if badarg == "0":
2007 # It's a sequence, and its elements are also sequences (gotta
2008 # love strings <wink>), but they aren't of length 2, so this
2009 # one seemed better as a ValueError than a TypeError.
2010 pass
2011 else:
2012 self.fail("no TypeError from dict(%r)" % badarg)
Michael W. Hudson98bbc492002-11-26 14:47:27 +00002013 else:
Georg Brandl48545522008-02-02 10:12:36 +00002014 self.fail("no TypeError from dict(%r)" % badarg)
Michael W. Hudson98bbc492002-11-26 14:47:27 +00002015
Georg Brandl48545522008-02-02 10:12:36 +00002016 try:
2017 dict({}, {})
2018 except TypeError:
2019 pass
2020 else:
2021 self.fail("no TypeError from dict({}, {})")
Michael W. Hudson98bbc492002-11-26 14:47:27 +00002022
Georg Brandl48545522008-02-02 10:12:36 +00002023 class Mapping:
2024 # Lacks a .keys() method; will be added later.
2025 dict = {1:2, 3:4, 'a':1j}
Michael W. Hudson98bbc492002-11-26 14:47:27 +00002026
Georg Brandl48545522008-02-02 10:12:36 +00002027 try:
2028 dict(Mapping())
2029 except TypeError:
2030 pass
2031 else:
2032 self.fail("no TypeError from dict(incomplete mapping)")
Michael W. Hudson98bbc492002-11-26 14:47:27 +00002033
Georg Brandl48545522008-02-02 10:12:36 +00002034 Mapping.keys = lambda self: self.dict.keys()
2035 Mapping.__getitem__ = lambda self, i: self.dict[i]
2036 d = dict(Mapping())
2037 self.assertEqual(d, Mapping.dict)
Michael W. Hudsonf3904422006-11-23 13:54:04 +00002038
Georg Brandl48545522008-02-02 10:12:36 +00002039 # Init from sequence of iterable objects, each producing a 2-sequence.
2040 class AddressBookEntry:
2041 def __init__(self, first, last):
2042 self.first = first
2043 self.last = last
2044 def __iter__(self):
2045 return iter([self.first, self.last])
Michael W. Hudson98bbc492002-11-26 14:47:27 +00002046
Georg Brandl48545522008-02-02 10:12:36 +00002047 d = dict([AddressBookEntry('Tim', 'Warsaw'),
2048 AddressBookEntry('Barry', 'Peters'),
2049 AddressBookEntry('Tim', 'Peters'),
2050 AddressBookEntry('Barry', 'Warsaw')])
2051 self.assertEqual(d, {'Barry': 'Warsaw', 'Tim': 'Peters'})
Guido van Rossum3bbc0ee2002-12-13 17:49:38 +00002052
Georg Brandl48545522008-02-02 10:12:36 +00002053 d = dict(zip(range(4), range(1, 5)))
2054 self.assertEqual(d, dict([(i, i+1) for i in range(4)]))
Michael W. Hudson98bbc492002-11-26 14:47:27 +00002055
Georg Brandl48545522008-02-02 10:12:36 +00002056 # Bad sequence lengths.
2057 for bad in [('tooshort',)], [('too', 'long', 'by 1')]:
2058 try:
2059 dict(bad)
2060 except ValueError:
2061 pass
Michael W. Hudson586da8f2002-11-27 15:20:19 +00002062 else:
Georg Brandl48545522008-02-02 10:12:36 +00002063 self.fail("no ValueError from dict(%r)" % bad)
2064
2065 def test_dir(self):
2066 # Testing dir() ...
2067 junk = 12
2068 self.assertEqual(dir(), ['junk', 'self'])
2069 del junk
2070
2071 # Just make sure these don't blow up!
2072 for arg in 2, 2L, 2j, 2e0, [2], "2", u"2", (2,), {2:2}, type, self.test_dir:
2073 dir(arg)
2074
2075 # Try classic classes.
2076 class C:
2077 Cdata = 1
2078 def Cmethod(self): pass
2079
2080 cstuff = ['Cdata', 'Cmethod', '__doc__', '__module__']
2081 self.assertEqual(dir(C), cstuff)
2082 self.assert_('im_self' in dir(C.Cmethod))
2083
2084 c = C() # c.__doc__ is an odd thing to see here; ditto c.__module__.
2085 self.assertEqual(dir(c), cstuff)
2086
2087 c.cdata = 2
2088 c.cmethod = lambda self: 0
2089 self.assertEqual(dir(c), cstuff + ['cdata', 'cmethod'])
2090 self.assert_('im_self' in dir(c.Cmethod))
2091
2092 class A(C):
2093 Adata = 1
2094 def Amethod(self): pass
2095
2096 astuff = ['Adata', 'Amethod'] + cstuff
2097 self.assertEqual(dir(A), astuff)
2098 self.assert_('im_self' in dir(A.Amethod))
2099 a = A()
2100 self.assertEqual(dir(a), astuff)
2101 self.assert_('im_self' in dir(a.Amethod))
2102 a.adata = 42
2103 a.amethod = lambda self: 3
2104 self.assertEqual(dir(a), astuff + ['adata', 'amethod'])
2105
2106 # The same, but with new-style classes. Since these have object as a
2107 # base class, a lot more gets sucked in.
2108 def interesting(strings):
2109 return [s for s in strings if not s.startswith('_')]
2110
2111 class C(object):
2112 Cdata = 1
2113 def Cmethod(self): pass
2114
2115 cstuff = ['Cdata', 'Cmethod']
2116 self.assertEqual(interesting(dir(C)), cstuff)
2117
2118 c = C()
2119 self.assertEqual(interesting(dir(c)), cstuff)
2120 self.assert_('im_self' in dir(C.Cmethod))
2121
2122 c.cdata = 2
2123 c.cmethod = lambda self: 0
2124 self.assertEqual(interesting(dir(c)), cstuff + ['cdata', 'cmethod'])
2125 self.assert_('im_self' in dir(c.Cmethod))
2126
2127 class A(C):
2128 Adata = 1
2129 def Amethod(self): pass
2130
2131 astuff = ['Adata', 'Amethod'] + cstuff
2132 self.assertEqual(interesting(dir(A)), astuff)
2133 self.assert_('im_self' in dir(A.Amethod))
2134 a = A()
2135 self.assertEqual(interesting(dir(a)), astuff)
2136 a.adata = 42
2137 a.amethod = lambda self: 3
2138 self.assertEqual(interesting(dir(a)), astuff + ['adata', 'amethod'])
2139 self.assert_('im_self' in dir(a.Amethod))
2140
2141 # Try a module subclass.
2142 import sys
2143 class M(type(sys)):
2144 pass
2145 minstance = M("m")
2146 minstance.b = 2
2147 minstance.a = 1
2148 names = [x for x in dir(minstance) if x not in ["__name__", "__doc__"]]
2149 self.assertEqual(names, ['a', 'b'])
2150
2151 class M2(M):
2152 def getdict(self):
2153 return "Not a dict!"
2154 __dict__ = property(getdict)
2155
2156 m2instance = M2("m2")
2157 m2instance.b = 2
2158 m2instance.a = 1
2159 self.assertEqual(m2instance.__dict__, "Not a dict!")
2160 try:
2161 dir(m2instance)
2162 except TypeError:
2163 pass
2164
2165 # Two essentially featureless objects, just inheriting stuff from
2166 # object.
2167 self.assertEqual(dir(None), dir(Ellipsis))
2168
2169 # Nasty test case for proxied objects
2170 class Wrapper(object):
2171 def __init__(self, obj):
2172 self.__obj = obj
2173 def __repr__(self):
2174 return "Wrapper(%s)" % repr(self.__obj)
2175 def __getitem__(self, key):
2176 return Wrapper(self.__obj[key])
2177 def __len__(self):
2178 return len(self.__obj)
2179 def __getattr__(self, name):
2180 return Wrapper(getattr(self.__obj, name))
2181
2182 class C(object):
2183 def __getclass(self):
2184 return Wrapper(type(self))
2185 __class__ = property(__getclass)
2186
2187 dir(C()) # This used to segfault
2188
2189 def test_supers(self):
2190 # Testing super...
2191
2192 class A(object):
2193 def meth(self, a):
2194 return "A(%r)" % a
2195
2196 self.assertEqual(A().meth(1), "A(1)")
2197
2198 class B(A):
2199 def __init__(self):
2200 self.__super = super(B, self)
2201 def meth(self, a):
2202 return "B(%r)" % a + self.__super.meth(a)
2203
2204 self.assertEqual(B().meth(2), "B(2)A(2)")
2205
2206 class C(A):
2207 def meth(self, a):
2208 return "C(%r)" % a + self.__super.meth(a)
2209 C._C__super = super(C)
2210
2211 self.assertEqual(C().meth(3), "C(3)A(3)")
2212
2213 class D(C, B):
2214 def meth(self, a):
2215 return "D(%r)" % a + super(D, self).meth(a)
2216
2217 self.assertEqual(D().meth(4), "D(4)C(4)B(4)A(4)")
2218
2219 # Test for subclassing super
2220
2221 class mysuper(super):
2222 def __init__(self, *args):
2223 return super(mysuper, self).__init__(*args)
2224
2225 class E(D):
2226 def meth(self, a):
2227 return "E(%r)" % a + mysuper(E, self).meth(a)
2228
2229 self.assertEqual(E().meth(5), "E(5)D(5)C(5)B(5)A(5)")
2230
2231 class F(E):
2232 def meth(self, a):
2233 s = self.__super # == mysuper(F, self)
2234 return "F(%r)[%s]" % (a, s.__class__.__name__) + s.meth(a)
2235 F._F__super = mysuper(F)
2236
2237 self.assertEqual(F().meth(6), "F(6)[mysuper]E(6)D(6)C(6)B(6)A(6)")
2238
2239 # Make sure certain errors are raised
2240
2241 try:
2242 super(D, 42)
2243 except TypeError:
2244 pass
2245 else:
2246 self.fail("shouldn't allow super(D, 42)")
2247
2248 try:
2249 super(D, C())
2250 except TypeError:
2251 pass
2252 else:
2253 self.fail("shouldn't allow super(D, C())")
2254
2255 try:
2256 super(D).__get__(12)
2257 except TypeError:
2258 pass
2259 else:
2260 self.fail("shouldn't allow super(D).__get__(12)")
2261
2262 try:
2263 super(D).__get__(C())
2264 except TypeError:
2265 pass
2266 else:
2267 self.fail("shouldn't allow super(D).__get__(C())")
2268
2269 # Make sure data descriptors can be overridden and accessed via super
2270 # (new feature in Python 2.3)
2271
2272 class DDbase(object):
2273 def getx(self): return 42
2274 x = property(getx)
2275
2276 class DDsub(DDbase):
2277 def getx(self): return "hello"
2278 x = property(getx)
2279
2280 dd = DDsub()
2281 self.assertEqual(dd.x, "hello")
2282 self.assertEqual(super(DDsub, dd).x, 42)
2283
2284 # Ensure that super() lookup of descriptor from classmethod
2285 # works (SF ID# 743627)
2286
2287 class Base(object):
2288 aProp = property(lambda self: "foo")
2289
2290 class Sub(Base):
2291 @classmethod
2292 def test(klass):
2293 return super(Sub,klass).aProp
2294
2295 self.assertEqual(Sub.test(), Base.aProp)
2296
2297 # Verify that super() doesn't allow keyword args
2298 try:
2299 super(Base, kw=1)
2300 except TypeError:
2301 pass
2302 else:
2303 self.assertEqual("super shouldn't accept keyword args")
2304
2305 def test_basic_inheritance(self):
2306 # Testing inheritance from basic types...
2307
2308 class hexint(int):
2309 def __repr__(self):
2310 return hex(self)
2311 def __add__(self, other):
2312 return hexint(int.__add__(self, other))
2313 # (Note that overriding __radd__ doesn't work,
2314 # because the int type gets first dibs.)
2315 self.assertEqual(repr(hexint(7) + 9), "0x10")
2316 self.assertEqual(repr(hexint(1000) + 7), "0x3ef")
2317 a = hexint(12345)
2318 self.assertEqual(a, 12345)
2319 self.assertEqual(int(a), 12345)
2320 self.assert_(int(a).__class__ is int)
2321 self.assertEqual(hash(a), hash(12345))
2322 self.assert_((+a).__class__ is int)
2323 self.assert_((a >> 0).__class__ is int)
2324 self.assert_((a << 0).__class__ is int)
2325 self.assert_((hexint(0) << 12).__class__ is int)
2326 self.assert_((hexint(0) >> 12).__class__ is int)
2327
2328 class octlong(long):
2329 __slots__ = []
2330 def __str__(self):
2331 s = oct(self)
2332 if s[-1] == 'L':
2333 s = s[:-1]
2334 return s
2335 def __add__(self, other):
2336 return self.__class__(super(octlong, self).__add__(other))
2337 __radd__ = __add__
2338 self.assertEqual(str(octlong(3) + 5), "010")
2339 # (Note that overriding __radd__ here only seems to work
2340 # because the example uses a short int left argument.)
2341 self.assertEqual(str(5 + octlong(3000)), "05675")
2342 a = octlong(12345)
2343 self.assertEqual(a, 12345L)
2344 self.assertEqual(long(a), 12345L)
2345 self.assertEqual(hash(a), hash(12345L))
2346 self.assert_(long(a).__class__ is long)
2347 self.assert_((+a).__class__ is long)
2348 self.assert_((-a).__class__ is long)
2349 self.assert_((-octlong(0)).__class__ is long)
2350 self.assert_((a >> 0).__class__ is long)
2351 self.assert_((a << 0).__class__ is long)
2352 self.assert_((a - 0).__class__ is long)
2353 self.assert_((a * 1).__class__ is long)
2354 self.assert_((a ** 1).__class__ is long)
2355 self.assert_((a // 1).__class__ is long)
2356 self.assert_((1 * a).__class__ is long)
2357 self.assert_((a | 0).__class__ is long)
2358 self.assert_((a ^ 0).__class__ is long)
2359 self.assert_((a & -1L).__class__ is long)
2360 self.assert_((octlong(0) << 12).__class__ is long)
2361 self.assert_((octlong(0) >> 12).__class__ is long)
2362 self.assert_(abs(octlong(0)).__class__ is long)
2363
2364 # Because octlong overrides __add__, we can't check the absence of +0
2365 # optimizations using octlong.
2366 class longclone(long):
2367 pass
2368 a = longclone(1)
2369 self.assert_((a + 0).__class__ is long)
2370 self.assert_((0 + a).__class__ is long)
2371
2372 # Check that negative clones don't segfault
2373 a = longclone(-1)
2374 self.assertEqual(a.__dict__, {})
2375 self.assertEqual(long(a), -1) # self.assert_ PyNumber_Long() copies the sign bit
2376
2377 class precfloat(float):
2378 __slots__ = ['prec']
2379 def __init__(self, value=0.0, prec=12):
2380 self.prec = int(prec)
2381 def __repr__(self):
2382 return "%.*g" % (self.prec, self)
2383 self.assertEqual(repr(precfloat(1.1)), "1.1")
2384 a = precfloat(12345)
2385 self.assertEqual(a, 12345.0)
2386 self.assertEqual(float(a), 12345.0)
2387 self.assert_(float(a).__class__ is float)
2388 self.assertEqual(hash(a), hash(12345.0))
2389 self.assert_((+a).__class__ is float)
2390
2391 class madcomplex(complex):
2392 def __repr__(self):
2393 return "%.17gj%+.17g" % (self.imag, self.real)
2394 a = madcomplex(-3, 4)
2395 self.assertEqual(repr(a), "4j-3")
2396 base = complex(-3, 4)
2397 self.assertEqual(base.__class__, complex)
2398 self.assertEqual(a, base)
2399 self.assertEqual(complex(a), base)
2400 self.assertEqual(complex(a).__class__, complex)
2401 a = madcomplex(a) # just trying another form of the constructor
2402 self.assertEqual(repr(a), "4j-3")
2403 self.assertEqual(a, base)
2404 self.assertEqual(complex(a), base)
2405 self.assertEqual(complex(a).__class__, complex)
2406 self.assertEqual(hash(a), hash(base))
2407 self.assertEqual((+a).__class__, complex)
2408 self.assertEqual((a + 0).__class__, complex)
2409 self.assertEqual(a + 0, base)
2410 self.assertEqual((a - 0).__class__, complex)
2411 self.assertEqual(a - 0, base)
2412 self.assertEqual((a * 1).__class__, complex)
2413 self.assertEqual(a * 1, base)
2414 self.assertEqual((a / 1).__class__, complex)
2415 self.assertEqual(a / 1, base)
2416
2417 class madtuple(tuple):
2418 _rev = None
2419 def rev(self):
2420 if self._rev is not None:
2421 return self._rev
2422 L = list(self)
2423 L.reverse()
2424 self._rev = self.__class__(L)
2425 return self._rev
2426 a = madtuple((1,2,3,4,5,6,7,8,9,0))
2427 self.assertEqual(a, (1,2,3,4,5,6,7,8,9,0))
2428 self.assertEqual(a.rev(), madtuple((0,9,8,7,6,5,4,3,2,1)))
2429 self.assertEqual(a.rev().rev(), madtuple((1,2,3,4,5,6,7,8,9,0)))
2430 for i in range(512):
2431 t = madtuple(range(i))
2432 u = t.rev()
2433 v = u.rev()
2434 self.assertEqual(v, t)
2435 a = madtuple((1,2,3,4,5))
2436 self.assertEqual(tuple(a), (1,2,3,4,5))
2437 self.assert_(tuple(a).__class__ is tuple)
2438 self.assertEqual(hash(a), hash((1,2,3,4,5)))
2439 self.assert_(a[:].__class__ is tuple)
2440 self.assert_((a * 1).__class__ is tuple)
2441 self.assert_((a * 0).__class__ is tuple)
2442 self.assert_((a + ()).__class__ is tuple)
2443 a = madtuple(())
2444 self.assertEqual(tuple(a), ())
2445 self.assert_(tuple(a).__class__ is tuple)
2446 self.assert_((a + a).__class__ is tuple)
2447 self.assert_((a * 0).__class__ is tuple)
2448 self.assert_((a * 1).__class__ is tuple)
2449 self.assert_((a * 2).__class__ is tuple)
2450 self.assert_(a[:].__class__ is tuple)
2451
2452 class madstring(str):
2453 _rev = None
2454 def rev(self):
2455 if self._rev is not None:
2456 return self._rev
2457 L = list(self)
2458 L.reverse()
2459 self._rev = self.__class__("".join(L))
2460 return self._rev
2461 s = madstring("abcdefghijklmnopqrstuvwxyz")
2462 self.assertEqual(s, "abcdefghijklmnopqrstuvwxyz")
2463 self.assertEqual(s.rev(), madstring("zyxwvutsrqponmlkjihgfedcba"))
2464 self.assertEqual(s.rev().rev(), madstring("abcdefghijklmnopqrstuvwxyz"))
2465 for i in range(256):
2466 s = madstring("".join(map(chr, range(i))))
2467 t = s.rev()
2468 u = t.rev()
2469 self.assertEqual(u, s)
2470 s = madstring("12345")
2471 self.assertEqual(str(s), "12345")
2472 self.assert_(str(s).__class__ is str)
2473
2474 base = "\x00" * 5
2475 s = madstring(base)
2476 self.assertEqual(s, base)
2477 self.assertEqual(str(s), base)
2478 self.assert_(str(s).__class__ is str)
2479 self.assertEqual(hash(s), hash(base))
2480 self.assertEqual({s: 1}[base], 1)
2481 self.assertEqual({base: 1}[s], 1)
2482 self.assert_((s + "").__class__ is str)
2483 self.assertEqual(s + "", base)
2484 self.assert_(("" + s).__class__ is str)
2485 self.assertEqual("" + s, base)
2486 self.assert_((s * 0).__class__ is str)
2487 self.assertEqual(s * 0, "")
2488 self.assert_((s * 1).__class__ is str)
2489 self.assertEqual(s * 1, base)
2490 self.assert_((s * 2).__class__ is str)
2491 self.assertEqual(s * 2, base + base)
2492 self.assert_(s[:].__class__ is str)
2493 self.assertEqual(s[:], base)
2494 self.assert_(s[0:0].__class__ is str)
2495 self.assertEqual(s[0:0], "")
2496 self.assert_(s.strip().__class__ is str)
2497 self.assertEqual(s.strip(), base)
2498 self.assert_(s.lstrip().__class__ is str)
2499 self.assertEqual(s.lstrip(), base)
2500 self.assert_(s.rstrip().__class__ is str)
2501 self.assertEqual(s.rstrip(), base)
2502 identitytab = ''.join([chr(i) for i in range(256)])
2503 self.assert_(s.translate(identitytab).__class__ is str)
2504 self.assertEqual(s.translate(identitytab), base)
2505 self.assert_(s.translate(identitytab, "x").__class__ is str)
2506 self.assertEqual(s.translate(identitytab, "x"), base)
2507 self.assertEqual(s.translate(identitytab, "\x00"), "")
2508 self.assert_(s.replace("x", "x").__class__ is str)
2509 self.assertEqual(s.replace("x", "x"), base)
2510 self.assert_(s.ljust(len(s)).__class__ is str)
2511 self.assertEqual(s.ljust(len(s)), base)
2512 self.assert_(s.rjust(len(s)).__class__ is str)
2513 self.assertEqual(s.rjust(len(s)), base)
2514 self.assert_(s.center(len(s)).__class__ is str)
2515 self.assertEqual(s.center(len(s)), base)
2516 self.assert_(s.lower().__class__ is str)
2517 self.assertEqual(s.lower(), base)
2518
2519 class madunicode(unicode):
2520 _rev = None
2521 def rev(self):
2522 if self._rev is not None:
2523 return self._rev
2524 L = list(self)
2525 L.reverse()
2526 self._rev = self.__class__(u"".join(L))
2527 return self._rev
2528 u = madunicode("ABCDEF")
2529 self.assertEqual(u, u"ABCDEF")
2530 self.assertEqual(u.rev(), madunicode(u"FEDCBA"))
2531 self.assertEqual(u.rev().rev(), madunicode(u"ABCDEF"))
2532 base = u"12345"
2533 u = madunicode(base)
2534 self.assertEqual(unicode(u), base)
2535 self.assert_(unicode(u).__class__ is unicode)
2536 self.assertEqual(hash(u), hash(base))
2537 self.assertEqual({u: 1}[base], 1)
2538 self.assertEqual({base: 1}[u], 1)
2539 self.assert_(u.strip().__class__ is unicode)
2540 self.assertEqual(u.strip(), base)
2541 self.assert_(u.lstrip().__class__ is unicode)
2542 self.assertEqual(u.lstrip(), base)
2543 self.assert_(u.rstrip().__class__ is unicode)
2544 self.assertEqual(u.rstrip(), base)
2545 self.assert_(u.replace(u"x", u"x").__class__ is unicode)
2546 self.assertEqual(u.replace(u"x", u"x"), base)
2547 self.assert_(u.replace(u"xy", u"xy").__class__ is unicode)
2548 self.assertEqual(u.replace(u"xy", u"xy"), base)
2549 self.assert_(u.center(len(u)).__class__ is unicode)
2550 self.assertEqual(u.center(len(u)), base)
2551 self.assert_(u.ljust(len(u)).__class__ is unicode)
2552 self.assertEqual(u.ljust(len(u)), base)
2553 self.assert_(u.rjust(len(u)).__class__ is unicode)
2554 self.assertEqual(u.rjust(len(u)), base)
2555 self.assert_(u.lower().__class__ is unicode)
2556 self.assertEqual(u.lower(), base)
2557 self.assert_(u.upper().__class__ is unicode)
2558 self.assertEqual(u.upper(), base)
2559 self.assert_(u.capitalize().__class__ is unicode)
2560 self.assertEqual(u.capitalize(), base)
2561 self.assert_(u.title().__class__ is unicode)
2562 self.assertEqual(u.title(), base)
2563 self.assert_((u + u"").__class__ is unicode)
2564 self.assertEqual(u + u"", base)
2565 self.assert_((u"" + u).__class__ is unicode)
2566 self.assertEqual(u"" + u, base)
2567 self.assert_((u * 0).__class__ is unicode)
2568 self.assertEqual(u * 0, u"")
2569 self.assert_((u * 1).__class__ is unicode)
2570 self.assertEqual(u * 1, base)
2571 self.assert_((u * 2).__class__ is unicode)
2572 self.assertEqual(u * 2, base + base)
2573 self.assert_(u[:].__class__ is unicode)
2574 self.assertEqual(u[:], base)
2575 self.assert_(u[0:0].__class__ is unicode)
2576 self.assertEqual(u[0:0], u"")
2577
2578 class sublist(list):
2579 pass
2580 a = sublist(range(5))
2581 self.assertEqual(a, range(5))
2582 a.append("hello")
2583 self.assertEqual(a, range(5) + ["hello"])
2584 a[5] = 5
2585 self.assertEqual(a, range(6))
2586 a.extend(range(6, 20))
2587 self.assertEqual(a, range(20))
2588 a[-5:] = []
2589 self.assertEqual(a, range(15))
2590 del a[10:15]
2591 self.assertEqual(len(a), 10)
2592 self.assertEqual(a, range(10))
2593 self.assertEqual(list(a), range(10))
2594 self.assertEqual(a[0], 0)
2595 self.assertEqual(a[9], 9)
2596 self.assertEqual(a[-10], 0)
2597 self.assertEqual(a[-1], 9)
2598 self.assertEqual(a[:5], range(5))
2599
2600 class CountedInput(file):
2601 """Counts lines read by self.readline().
2602
2603 self.lineno is the 0-based ordinal of the last line read, up to
2604 a maximum of one greater than the number of lines in the file.
2605
2606 self.ateof is true if and only if the final "" line has been read,
2607 at which point self.lineno stops incrementing, and further calls
2608 to readline() continue to return "".
2609 """
2610
2611 lineno = 0
2612 ateof = 0
2613 def readline(self):
2614 if self.ateof:
2615 return ""
2616 s = file.readline(self)
2617 # Next line works too.
2618 # s = super(CountedInput, self).readline()
2619 self.lineno += 1
2620 if s == "":
2621 self.ateof = 1
2622 return s
2623
2624 f = file(name=test_support.TESTFN, mode='w')
2625 lines = ['a\n', 'b\n', 'c\n']
2626 try:
2627 f.writelines(lines)
2628 f.close()
2629 f = CountedInput(test_support.TESTFN)
2630 for (i, expected) in zip(range(1, 5) + [4], lines + 2 * [""]):
2631 got = f.readline()
2632 self.assertEqual(expected, got)
2633 self.assertEqual(f.lineno, i)
2634 self.assertEqual(f.ateof, (i > len(lines)))
2635 f.close()
2636 finally:
2637 try:
2638 f.close()
2639 except:
2640 pass
2641 test_support.unlink(test_support.TESTFN)
2642
2643 def test_keywords(self):
2644 # Testing keyword args to basic type constructors ...
2645 self.assertEqual(int(x=1), 1)
2646 self.assertEqual(float(x=2), 2.0)
2647 self.assertEqual(long(x=3), 3L)
2648 self.assertEqual(complex(imag=42, real=666), complex(666, 42))
2649 self.assertEqual(str(object=500), '500')
2650 self.assertEqual(unicode(string='abc', errors='strict'), u'abc')
2651 self.assertEqual(tuple(sequence=range(3)), (0, 1, 2))
2652 self.assertEqual(list(sequence=(0, 1, 2)), range(3))
2653 # note: as of Python 2.3, dict() no longer has an "items" keyword arg
2654
2655 for constructor in (int, float, long, complex, str, unicode,
2656 tuple, list, file):
2657 try:
2658 constructor(bogus_keyword_arg=1)
2659 except TypeError:
2660 pass
2661 else:
2662 self.fail("expected TypeError from bogus keyword argument to %r"
2663 % constructor)
2664
2665 def test_str_subclass_as_dict_key(self):
2666 # Testing a str subclass used as dict key ..
2667
2668 class cistr(str):
2669 """Sublcass of str that computes __eq__ case-insensitively.
2670
2671 Also computes a hash code of the string in canonical form.
2672 """
2673
2674 def __init__(self, value):
2675 self.canonical = value.lower()
2676 self.hashcode = hash(self.canonical)
2677
2678 def __eq__(self, other):
2679 if not isinstance(other, cistr):
2680 other = cistr(other)
2681 return self.canonical == other.canonical
2682
2683 def __hash__(self):
2684 return self.hashcode
2685
2686 self.assertEqual(cistr('ABC'), 'abc')
2687 self.assertEqual('aBc', cistr('ABC'))
2688 self.assertEqual(str(cistr('ABC')), 'ABC')
2689
2690 d = {cistr('one'): 1, cistr('two'): 2, cistr('tHree'): 3}
2691 self.assertEqual(d[cistr('one')], 1)
2692 self.assertEqual(d[cistr('tWo')], 2)
2693 self.assertEqual(d[cistr('THrEE')], 3)
2694 self.assert_(cistr('ONe') in d)
2695 self.assertEqual(d.get(cistr('thrEE')), 3)
2696
2697 def test_classic_comparisons(self):
2698 # Testing classic comparisons...
2699 class classic:
2700 pass
2701
2702 for base in (classic, int, object):
2703 class C(base):
2704 def __init__(self, value):
2705 self.value = int(value)
2706 def __cmp__(self, other):
2707 if isinstance(other, C):
2708 return cmp(self.value, other.value)
2709 if isinstance(other, int) or isinstance(other, long):
2710 return cmp(self.value, other)
2711 return NotImplemented
2712
2713 c1 = C(1)
2714 c2 = C(2)
2715 c3 = C(3)
2716 self.assertEqual(c1, 1)
2717 c = {1: c1, 2: c2, 3: c3}
2718 for x in 1, 2, 3:
2719 for y in 1, 2, 3:
2720 self.assert_(cmp(c[x], c[y]) == cmp(x, y), "x=%d, y=%d" % (x, y))
2721 for op in "<", "<=", "==", "!=", ">", ">=":
2722 self.assert_(eval("c[x] %s c[y]" % op) == eval("x %s y" % op),
2723 "x=%d, y=%d" % (x, y))
2724 self.assert_(cmp(c[x], y) == cmp(x, y), "x=%d, y=%d" % (x, y))
2725 self.assert_(cmp(x, c[y]) == cmp(x, y), "x=%d, y=%d" % (x, y))
2726
2727 def test_rich_comparisons(self):
2728 # Testing rich comparisons...
2729 class Z(complex):
2730 pass
2731 z = Z(1)
2732 self.assertEqual(z, 1+0j)
2733 self.assertEqual(1+0j, z)
2734 class ZZ(complex):
2735 def __eq__(self, other):
2736 try:
2737 return abs(self - other) <= 1e-6
2738 except:
2739 return NotImplemented
2740 zz = ZZ(1.0000003)
2741 self.assertEqual(zz, 1+0j)
2742 self.assertEqual(1+0j, zz)
2743
2744 class classic:
2745 pass
2746 for base in (classic, int, object, list):
2747 class C(base):
2748 def __init__(self, value):
2749 self.value = int(value)
2750 def __cmp__(self_, other):
2751 self.fail("shouldn't call __cmp__")
2752 def __eq__(self, other):
2753 if isinstance(other, C):
2754 return self.value == other.value
2755 if isinstance(other, int) or isinstance(other, long):
2756 return self.value == other
2757 return NotImplemented
2758 def __ne__(self, other):
2759 if isinstance(other, C):
2760 return self.value != other.value
2761 if isinstance(other, int) or isinstance(other, long):
2762 return self.value != other
2763 return NotImplemented
2764 def __lt__(self, other):
2765 if isinstance(other, C):
2766 return self.value < other.value
2767 if isinstance(other, int) or isinstance(other, long):
2768 return self.value < other
2769 return NotImplemented
2770 def __le__(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 __gt__(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 __ge__(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 c1 = C(1)
2789 c2 = C(2)
2790 c3 = C(3)
2791 self.assertEqual(c1, 1)
2792 c = {1: c1, 2: c2, 3: c3}
2793 for x in 1, 2, 3:
2794 for y in 1, 2, 3:
2795 for op in "<", "<=", "==", "!=", ">", ">=":
2796 self.assert_(eval("c[x] %s c[y]" % op) == eval("x %s y" % op),
2797 "x=%d, y=%d" % (x, y))
2798 self.assert_(eval("c[x] %s y" % op) == eval("x %s y" % op),
2799 "x=%d, y=%d" % (x, y))
2800 self.assert_(eval("x %s c[y]" % op) == eval("x %s y" % op),
2801 "x=%d, y=%d" % (x, y))
2802
2803 def test_coercions(self):
2804 # Testing coercions...
2805 class I(int): pass
2806 coerce(I(0), 0)
2807 coerce(0, I(0))
2808 class L(long): pass
2809 coerce(L(0), 0)
2810 coerce(L(0), 0L)
2811 coerce(0, L(0))
2812 coerce(0L, L(0))
2813 class F(float): pass
2814 coerce(F(0), 0)
2815 coerce(F(0), 0L)
2816 coerce(F(0), 0.)
2817 coerce(0, F(0))
2818 coerce(0L, F(0))
2819 coerce(0., F(0))
2820 class C(complex): pass
2821 coerce(C(0), 0)
2822 coerce(C(0), 0L)
2823 coerce(C(0), 0.)
2824 coerce(C(0), 0j)
2825 coerce(0, C(0))
2826 coerce(0L, C(0))
2827 coerce(0., C(0))
2828 coerce(0j, C(0))
2829
2830 def test_descrdoc(self):
2831 # Testing descriptor doc strings...
2832 def check(descr, what):
2833 self.assertEqual(descr.__doc__, what)
2834 check(file.closed, "True if the file is closed") # getset descriptor
2835 check(file.name, "file name") # member descriptor
2836
2837 def test_doc_descriptor(self):
2838 # Testing __doc__ descriptor...
2839 # SF bug 542984
2840 class DocDescr(object):
2841 def __get__(self, object, otype):
2842 if object:
2843 object = object.__class__.__name__ + ' instance'
2844 if otype:
2845 otype = otype.__name__
2846 return 'object=%s; type=%s' % (object, otype)
2847 class OldClass:
2848 __doc__ = DocDescr()
2849 class NewClass(object):
2850 __doc__ = DocDescr()
2851 self.assertEqual(OldClass.__doc__, 'object=None; type=OldClass')
2852 self.assertEqual(OldClass().__doc__, 'object=OldClass instance; type=OldClass')
2853 self.assertEqual(NewClass.__doc__, 'object=None; type=NewClass')
2854 self.assertEqual(NewClass().__doc__, 'object=NewClass instance; type=NewClass')
2855
2856 def test_set_class(self):
2857 # Testing __class__ assignment...
2858 class C(object): pass
2859 class D(object): pass
2860 class E(object): pass
2861 class F(D, E): pass
2862 for cls in C, D, E, F:
2863 for cls2 in C, D, E, F:
2864 x = cls()
2865 x.__class__ = cls2
2866 self.assert_(x.__class__ is cls2)
2867 x.__class__ = cls
2868 self.assert_(x.__class__ is cls)
2869 def cant(x, C):
2870 try:
2871 x.__class__ = C
2872 except TypeError:
2873 pass
2874 else:
2875 self.fail("shouldn't allow %r.__class__ = %r" % (x, C))
2876 try:
2877 delattr(x, "__class__")
2878 except TypeError:
2879 pass
2880 else:
2881 self.fail("shouldn't allow del %r.__class__" % x)
2882 cant(C(), list)
2883 cant(list(), C)
2884 cant(C(), 1)
2885 cant(C(), object)
2886 cant(object(), list)
2887 cant(list(), object)
2888 class Int(int): __slots__ = []
2889 cant(2, Int)
2890 cant(Int(), int)
2891 cant(True, int)
2892 cant(2, bool)
2893 o = object()
2894 cant(o, type(1))
2895 cant(o, type(None))
2896 del o
2897 class G(object):
2898 __slots__ = ["a", "b"]
2899 class H(object):
2900 __slots__ = ["b", "a"]
2901 try:
2902 unicode
2903 except NameError:
2904 class I(object):
2905 __slots__ = ["a", "b"]
2906 else:
2907 class I(object):
2908 __slots__ = [unicode("a"), unicode("b")]
2909 class J(object):
2910 __slots__ = ["c", "b"]
2911 class K(object):
2912 __slots__ = ["a", "b", "d"]
2913 class L(H):
2914 __slots__ = ["e"]
2915 class M(I):
2916 __slots__ = ["e"]
2917 class N(J):
2918 __slots__ = ["__weakref__"]
2919 class P(J):
2920 __slots__ = ["__dict__"]
2921 class Q(J):
2922 pass
2923 class R(J):
2924 __slots__ = ["__dict__", "__weakref__"]
2925
2926 for cls, cls2 in ((G, H), (G, I), (I, H), (Q, R), (R, Q)):
2927 x = cls()
2928 x.a = 1
2929 x.__class__ = cls2
2930 self.assert_(x.__class__ is cls2,
2931 "assigning %r as __class__ for %r silently failed" % (cls2, x))
2932 self.assertEqual(x.a, 1)
2933 x.__class__ = cls
2934 self.assert_(x.__class__ is cls,
2935 "assigning %r as __class__ for %r silently failed" % (cls, x))
2936 self.assertEqual(x.a, 1)
2937 for cls in G, J, K, L, M, N, P, R, list, Int:
2938 for cls2 in G, J, K, L, M, N, P, R, list, Int:
2939 if cls is cls2:
2940 continue
2941 cant(cls(), cls2)
2942
2943 def test_set_dict(self):
2944 # Testing __dict__ assignment...
2945 class C(object): pass
2946 a = C()
2947 a.__dict__ = {'b': 1}
2948 self.assertEqual(a.b, 1)
2949 def cant(x, dict):
2950 try:
2951 x.__dict__ = dict
2952 except (AttributeError, TypeError):
2953 pass
2954 else:
2955 self.fail("shouldn't allow %r.__dict__ = %r" % (x, dict))
2956 cant(a, None)
2957 cant(a, [])
2958 cant(a, 1)
2959 del a.__dict__ # Deleting __dict__ is allowed
2960
2961 class Base(object):
2962 pass
2963 def verify_dict_readonly(x):
2964 """
2965 x has to be an instance of a class inheriting from Base.
2966 """
2967 cant(x, {})
2968 try:
2969 del x.__dict__
2970 except (AttributeError, TypeError):
2971 pass
2972 else:
2973 self.fail("shouldn't allow del %r.__dict__" % x)
2974 dict_descr = Base.__dict__["__dict__"]
2975 try:
2976 dict_descr.__set__(x, {})
2977 except (AttributeError, TypeError):
2978 pass
2979 else:
2980 self.fail("dict_descr allowed access to %r's dict" % x)
2981
2982 # Classes don't allow __dict__ assignment and have readonly dicts
2983 class Meta1(type, Base):
2984 pass
2985 class Meta2(Base, type):
2986 pass
2987 class D(object):
2988 __metaclass__ = Meta1
2989 class E(object):
2990 __metaclass__ = Meta2
2991 for cls in C, D, E:
2992 verify_dict_readonly(cls)
2993 class_dict = cls.__dict__
2994 try:
2995 class_dict["spam"] = "eggs"
2996 except TypeError:
2997 pass
2998 else:
2999 self.fail("%r's __dict__ can be modified" % cls)
3000
3001 # Modules also disallow __dict__ assignment
3002 class Module1(types.ModuleType, Base):
3003 pass
3004 class Module2(Base, types.ModuleType):
3005 pass
3006 for ModuleType in Module1, Module2:
3007 mod = ModuleType("spam")
3008 verify_dict_readonly(mod)
3009 mod.__dict__["spam"] = "eggs"
3010
3011 # Exception's __dict__ can be replaced, but not deleted
3012 class Exception1(Exception, Base):
3013 pass
3014 class Exception2(Base, Exception):
3015 pass
3016 for ExceptionType in Exception, Exception1, Exception2:
3017 e = ExceptionType()
3018 e.__dict__ = {"a": 1}
3019 self.assertEqual(e.a, 1)
3020 try:
3021 del e.__dict__
3022 except (TypeError, AttributeError):
3023 pass
3024 else:
3025 self.fail("%r's __dict__ can be deleted" % e)
3026
3027 def test_pickles(self):
3028 # Testing pickling and copying new-style classes and objects...
3029 import pickle, cPickle
3030
3031 def sorteditems(d):
3032 L = d.items()
3033 L.sort()
3034 return L
3035
3036 global C
3037 class C(object):
3038 def __init__(self, a, b):
3039 super(C, self).__init__()
3040 self.a = a
3041 self.b = b
3042 def __repr__(self):
3043 return "C(%r, %r)" % (self.a, self.b)
3044
3045 global C1
3046 class C1(list):
3047 def __new__(cls, a, b):
3048 return super(C1, cls).__new__(cls)
3049 def __getnewargs__(self):
3050 return (self.a, self.b)
3051 def __init__(self, a, b):
3052 self.a = a
3053 self.b = b
3054 def __repr__(self):
3055 return "C1(%r, %r)<%r>" % (self.a, self.b, list(self))
3056
3057 global C2
3058 class C2(int):
3059 def __new__(cls, a, b, val=0):
3060 return super(C2, cls).__new__(cls, val)
3061 def __getnewargs__(self):
3062 return (self.a, self.b, int(self))
3063 def __init__(self, a, b, val=0):
3064 self.a = a
3065 self.b = b
3066 def __repr__(self):
3067 return "C2(%r, %r)<%r>" % (self.a, self.b, int(self))
3068
3069 global C3
3070 class C3(object):
3071 def __init__(self, foo):
3072 self.foo = foo
3073 def __getstate__(self):
3074 return self.foo
3075 def __setstate__(self, foo):
3076 self.foo = foo
3077
3078 global C4classic, C4
3079 class C4classic: # classic
3080 pass
3081 class C4(C4classic, object): # mixed inheritance
3082 pass
3083
3084 for p in pickle, cPickle:
3085 for bin in 0, 1:
3086 for cls in C, C1, C2:
3087 s = p.dumps(cls, bin)
3088 cls2 = p.loads(s)
3089 self.assert_(cls2 is cls)
3090
3091 a = C1(1, 2); a.append(42); a.append(24)
3092 b = C2("hello", "world", 42)
3093 s = p.dumps((a, b), bin)
3094 x, y = p.loads(s)
3095 self.assertEqual(x.__class__, a.__class__)
3096 self.assertEqual(sorteditems(x.__dict__), sorteditems(a.__dict__))
3097 self.assertEqual(y.__class__, b.__class__)
3098 self.assertEqual(sorteditems(y.__dict__), sorteditems(b.__dict__))
3099 self.assertEqual(repr(x), repr(a))
3100 self.assertEqual(repr(y), repr(b))
3101 # Test for __getstate__ and __setstate__ on new style class
3102 u = C3(42)
3103 s = p.dumps(u, bin)
3104 v = p.loads(s)
3105 self.assertEqual(u.__class__, v.__class__)
3106 self.assertEqual(u.foo, v.foo)
3107 # Test for picklability of hybrid class
3108 u = C4()
3109 u.foo = 42
3110 s = p.dumps(u, bin)
3111 v = p.loads(s)
3112 self.assertEqual(u.__class__, v.__class__)
3113 self.assertEqual(u.foo, v.foo)
3114
3115 # Testing copy.deepcopy()
3116 import copy
3117 for cls in C, C1, C2:
3118 cls2 = copy.deepcopy(cls)
3119 self.assert_(cls2 is cls)
3120
3121 a = C1(1, 2); a.append(42); a.append(24)
3122 b = C2("hello", "world", 42)
3123 x, y = copy.deepcopy((a, b))
3124 self.assertEqual(x.__class__, a.__class__)
3125 self.assertEqual(sorteditems(x.__dict__), sorteditems(a.__dict__))
3126 self.assertEqual(y.__class__, b.__class__)
3127 self.assertEqual(sorteditems(y.__dict__), sorteditems(b.__dict__))
3128 self.assertEqual(repr(x), repr(a))
3129 self.assertEqual(repr(y), repr(b))
3130
3131 def test_pickle_slots(self):
3132 # Testing pickling of classes with __slots__ ...
3133 import pickle, cPickle
3134 # Pickling of classes with __slots__ but without __getstate__ should fail
3135 global B, C, D, E
3136 class B(object):
3137 pass
3138 for base in [object, B]:
3139 class C(base):
3140 __slots__ = ['a']
3141 class D(C):
3142 pass
3143 try:
3144 pickle.dumps(C())
3145 except TypeError:
3146 pass
3147 else:
3148 self.fail("should fail: pickle C instance - %s" % base)
3149 try:
3150 cPickle.dumps(C())
3151 except TypeError:
3152 pass
3153 else:
3154 self.fail("should fail: cPickle C instance - %s" % base)
3155 try:
3156 pickle.dumps(C())
3157 except TypeError:
3158 pass
3159 else:
3160 self.fail("should fail: pickle D instance - %s" % base)
3161 try:
3162 cPickle.dumps(D())
3163 except TypeError:
3164 pass
3165 else:
3166 self.fail("should fail: cPickle D instance - %s" % base)
3167 # Give C a nice generic __getstate__ and __setstate__
3168 class C(base):
3169 __slots__ = ['a']
3170 def __getstate__(self):
3171 try:
3172 d = self.__dict__.copy()
3173 except AttributeError:
3174 d = {}
3175 for cls in self.__class__.__mro__:
3176 for sn in cls.__dict__.get('__slots__', ()):
3177 try:
3178 d[sn] = getattr(self, sn)
3179 except AttributeError:
3180 pass
3181 return d
3182 def __setstate__(self, d):
3183 for k, v in d.items():
3184 setattr(self, k, v)
3185 class D(C):
3186 pass
3187 # Now it should work
3188 x = C()
3189 y = pickle.loads(pickle.dumps(x))
3190 self.assertEqual(hasattr(y, 'a'), 0)
3191 y = cPickle.loads(cPickle.dumps(x))
3192 self.assertEqual(hasattr(y, 'a'), 0)
3193 x.a = 42
3194 y = pickle.loads(pickle.dumps(x))
3195 self.assertEqual(y.a, 42)
3196 y = cPickle.loads(cPickle.dumps(x))
3197 self.assertEqual(y.a, 42)
3198 x = D()
3199 x.a = 42
3200 x.b = 100
3201 y = pickle.loads(pickle.dumps(x))
3202 self.assertEqual(y.a + y.b, 142)
3203 y = cPickle.loads(cPickle.dumps(x))
3204 self.assertEqual(y.a + y.b, 142)
3205 # A subclass that adds a slot should also work
3206 class E(C):
3207 __slots__ = ['b']
3208 x = E()
3209 x.a = 42
3210 x.b = "foo"
3211 y = pickle.loads(pickle.dumps(x))
3212 self.assertEqual(y.a, x.a)
3213 self.assertEqual(y.b, x.b)
3214 y = cPickle.loads(cPickle.dumps(x))
3215 self.assertEqual(y.a, x.a)
3216 self.assertEqual(y.b, x.b)
3217
3218 def test_binary_operator_override(self):
3219 # Testing overrides of binary operations...
3220 class I(int):
3221 def __repr__(self):
3222 return "I(%r)" % int(self)
3223 def __add__(self, other):
3224 return I(int(self) + int(other))
3225 __radd__ = __add__
3226 def __pow__(self, other, mod=None):
3227 if mod is None:
3228 return I(pow(int(self), int(other)))
3229 else:
3230 return I(pow(int(self), int(other), int(mod)))
3231 def __rpow__(self, other, mod=None):
3232 if mod is None:
3233 return I(pow(int(other), int(self), mod))
3234 else:
3235 return I(pow(int(other), int(self), int(mod)))
3236
3237 self.assertEqual(repr(I(1) + I(2)), "I(3)")
3238 self.assertEqual(repr(I(1) + 2), "I(3)")
3239 self.assertEqual(repr(1 + I(2)), "I(3)")
3240 self.assertEqual(repr(I(2) ** I(3)), "I(8)")
3241 self.assertEqual(repr(2 ** I(3)), "I(8)")
3242 self.assertEqual(repr(I(2) ** 3), "I(8)")
3243 self.assertEqual(repr(pow(I(2), I(3), I(5))), "I(3)")
3244 class S(str):
3245 def __eq__(self, other):
3246 return self.lower() == other.lower()
3247
3248 def test_subclass_propagation(self):
3249 # Testing propagation of slot functions to subclasses...
3250 class A(object):
3251 pass
3252 class B(A):
3253 pass
3254 class C(A):
3255 pass
3256 class D(B, C):
3257 pass
3258 d = D()
3259 orig_hash = hash(d) # related to id(d) in platform-dependent ways
3260 A.__hash__ = lambda self: 42
3261 self.assertEqual(hash(d), 42)
3262 C.__hash__ = lambda self: 314
3263 self.assertEqual(hash(d), 314)
3264 B.__hash__ = lambda self: 144
3265 self.assertEqual(hash(d), 144)
3266 D.__hash__ = lambda self: 100
3267 self.assertEqual(hash(d), 100)
3268 del D.__hash__
3269 self.assertEqual(hash(d), 144)
3270 del B.__hash__
3271 self.assertEqual(hash(d), 314)
3272 del C.__hash__
3273 self.assertEqual(hash(d), 42)
3274 del A.__hash__
3275 self.assertEqual(hash(d), orig_hash)
3276 d.foo = 42
3277 d.bar = 42
3278 self.assertEqual(d.foo, 42)
3279 self.assertEqual(d.bar, 42)
3280 def __getattribute__(self, name):
3281 if name == "foo":
3282 return 24
3283 return object.__getattribute__(self, name)
3284 A.__getattribute__ = __getattribute__
3285 self.assertEqual(d.foo, 24)
3286 self.assertEqual(d.bar, 42)
3287 def __getattr__(self, name):
3288 if name in ("spam", "foo", "bar"):
3289 return "hello"
3290 raise AttributeError, name
3291 B.__getattr__ = __getattr__
3292 self.assertEqual(d.spam, "hello")
3293 self.assertEqual(d.foo, 24)
3294 self.assertEqual(d.bar, 42)
3295 del A.__getattribute__
3296 self.assertEqual(d.foo, 42)
3297 del d.foo
3298 self.assertEqual(d.foo, "hello")
3299 self.assertEqual(d.bar, 42)
3300 del B.__getattr__
3301 try:
3302 d.foo
3303 except AttributeError:
3304 pass
3305 else:
3306 self.fail("d.foo should be undefined now")
3307
3308 # Test a nasty bug in recurse_down_subclasses()
3309 import gc
3310 class A(object):
3311 pass
3312 class B(A):
3313 pass
3314 del B
3315 gc.collect()
3316 A.__setitem__ = lambda *a: None # crash
3317
3318 def test_buffer_inheritance(self):
3319 # Testing that buffer interface is inherited ...
3320
3321 import binascii
3322 # SF bug [#470040] ParseTuple t# vs subclasses.
3323
3324 class MyStr(str):
3325 pass
3326 base = 'abc'
3327 m = MyStr(base)
3328 # b2a_hex uses the buffer interface to get its argument's value, via
3329 # PyArg_ParseTuple 't#' code.
3330 self.assertEqual(binascii.b2a_hex(m), binascii.b2a_hex(base))
3331
3332 # It's not clear that unicode will continue to support the character
3333 # buffer interface, and this test will fail if that's taken away.
3334 class MyUni(unicode):
3335 pass
3336 base = u'abc'
3337 m = MyUni(base)
3338 self.assertEqual(binascii.b2a_hex(m), binascii.b2a_hex(base))
3339
3340 class MyInt(int):
3341 pass
3342 m = MyInt(42)
3343 try:
3344 binascii.b2a_hex(m)
3345 self.fail('subclass of int should not have a buffer interface')
3346 except TypeError:
3347 pass
3348
3349 def test_str_of_str_subclass(self):
3350 # Testing __str__ defined in subclass of str ...
3351 import binascii
3352 import cStringIO
3353
3354 class octetstring(str):
3355 def __str__(self):
3356 return binascii.b2a_hex(self)
3357 def __repr__(self):
3358 return self + " repr"
3359
3360 o = octetstring('A')
3361 self.assertEqual(type(o), octetstring)
3362 self.assertEqual(type(str(o)), str)
3363 self.assertEqual(type(repr(o)), str)
3364 self.assertEqual(ord(o), 0x41)
3365 self.assertEqual(str(o), '41')
3366 self.assertEqual(repr(o), 'A repr')
3367 self.assertEqual(o.__str__(), '41')
3368 self.assertEqual(o.__repr__(), 'A repr')
3369
3370 capture = cStringIO.StringIO()
3371 # Calling str() or not exercises different internal paths.
3372 print >> capture, o
3373 print >> capture, str(o)
3374 self.assertEqual(capture.getvalue(), '41\n41\n')
3375 capture.close()
3376
3377 def test_keyword_arguments(self):
3378 # Testing keyword arguments to __init__, __call__...
3379 def f(a): return a
3380 self.assertEqual(f.__call__(a=42), 42)
3381 a = []
3382 list.__init__(a, sequence=[0, 1, 2])
3383 self.assertEqual(a, [0, 1, 2])
3384
3385 def test_recursive_call(self):
3386 # Testing recursive __call__() by setting to instance of class...
3387 class A(object):
3388 pass
3389
3390 A.__call__ = A()
3391 try:
3392 A()()
3393 except RuntimeError:
3394 pass
3395 else:
3396 self.fail("Recursion limit should have been reached for __call__()")
3397
3398 def test_delete_hook(self):
3399 # Testing __del__ hook...
3400 log = []
3401 class C(object):
3402 def __del__(self):
3403 log.append(1)
3404 c = C()
3405 self.assertEqual(log, [])
3406 del c
3407 self.assertEqual(log, [1])
3408
3409 class D(object): pass
3410 d = D()
3411 try: del d[0]
3412 except TypeError: pass
3413 else: self.fail("invalid del() didn't raise TypeError")
3414
3415 def test_hash_inheritance(self):
3416 # Testing hash of mutable subclasses...
3417
3418 class mydict(dict):
3419 pass
3420 d = mydict()
3421 try:
3422 hash(d)
3423 except TypeError:
3424 pass
3425 else:
3426 self.fail("hash() of dict subclass should fail")
3427
3428 class mylist(list):
3429 pass
3430 d = mylist()
3431 try:
3432 hash(d)
3433 except TypeError:
3434 pass
3435 else:
3436 self.fail("hash() of list subclass should fail")
3437
3438 def test_str_operations(self):
3439 try: 'a' + 5
3440 except TypeError: pass
3441 else: self.fail("'' + 5 doesn't raise TypeError")
3442
3443 try: ''.split('')
3444 except ValueError: pass
3445 else: self.fail("''.split('') doesn't raise ValueError")
3446
3447 try: ''.join([0])
3448 except TypeError: pass
3449 else: self.fail("''.join([0]) doesn't raise TypeError")
3450
3451 try: ''.rindex('5')
3452 except ValueError: pass
3453 else: self.fail("''.rindex('5') doesn't raise ValueError")
3454
3455 try: '%(n)s' % None
3456 except TypeError: pass
3457 else: self.fail("'%(n)s' % None doesn't raise TypeError")
3458
3459 try: '%(n' % {}
3460 except ValueError: pass
3461 else: self.fail("'%(n' % {} '' doesn't raise ValueError")
3462
3463 try: '%*s' % ('abc')
3464 except TypeError: pass
3465 else: self.fail("'%*s' % ('abc') doesn't raise TypeError")
3466
3467 try: '%*.*s' % ('abc', 5)
3468 except TypeError: pass
3469 else: self.fail("'%*.*s' % ('abc', 5) doesn't raise TypeError")
3470
3471 try: '%s' % (1, 2)
3472 except TypeError: pass
3473 else: self.fail("'%s' % (1, 2) doesn't raise TypeError")
3474
3475 try: '%' % None
3476 except ValueError: pass
3477 else: self.fail("'%' % None doesn't raise ValueError")
3478
3479 self.assertEqual('534253'.isdigit(), 1)
3480 self.assertEqual('534253x'.isdigit(), 0)
3481 self.assertEqual('%c' % 5, '\x05')
3482 self.assertEqual('%c' % '5', '5')
3483
3484 def test_deepcopy_recursive(self):
3485 # Testing deepcopy of recursive objects...
3486 class Node:
3487 pass
3488 a = Node()
3489 b = Node()
3490 a.b = b
3491 b.a = a
3492 z = deepcopy(a) # This blew up before
3493
3494 def test_unintialized_modules(self):
3495 # Testing uninitialized module objects...
3496 from types import ModuleType as M
3497 m = M.__new__(M)
3498 str(m)
3499 self.assertEqual(hasattr(m, "__name__"), 0)
3500 self.assertEqual(hasattr(m, "__file__"), 0)
3501 self.assertEqual(hasattr(m, "foo"), 0)
3502 self.assertEqual(m.__dict__, None)
3503 m.foo = 1
3504 self.assertEqual(m.__dict__, {"foo": 1})
3505
3506 def test_funny_new(self):
3507 # Testing __new__ returning something unexpected...
3508 class C(object):
3509 def __new__(cls, arg):
3510 if isinstance(arg, str): return [1, 2, 3]
3511 elif isinstance(arg, int): return object.__new__(D)
3512 else: return object.__new__(cls)
3513 class D(C):
3514 def __init__(self, arg):
3515 self.foo = arg
3516 self.assertEqual(C("1"), [1, 2, 3])
3517 self.assertEqual(D("1"), [1, 2, 3])
3518 d = D(None)
3519 self.assertEqual(d.foo, None)
3520 d = C(1)
3521 self.assertEqual(isinstance(d, D), True)
3522 self.assertEqual(d.foo, 1)
3523 d = D(1)
3524 self.assertEqual(isinstance(d, D), True)
3525 self.assertEqual(d.foo, 1)
3526
3527 def test_imul_bug(self):
3528 # Testing for __imul__ problems...
3529 # SF bug 544647
3530 class C(object):
3531 def __imul__(self, other):
3532 return (self, other)
3533 x = C()
3534 y = x
3535 y *= 1.0
3536 self.assertEqual(y, (x, 1.0))
3537 y = x
3538 y *= 2
3539 self.assertEqual(y, (x, 2))
3540 y = x
3541 y *= 3L
3542 self.assertEqual(y, (x, 3L))
3543 y = x
3544 y *= 1L<<100
3545 self.assertEqual(y, (x, 1L<<100))
3546 y = x
3547 y *= None
3548 self.assertEqual(y, (x, None))
3549 y = x
3550 y *= "foo"
3551 self.assertEqual(y, (x, "foo"))
3552
3553 def test_copy_setstate(self):
3554 # Testing that copy.*copy() correctly uses __setstate__...
3555 import copy
3556 class C(object):
3557 def __init__(self, foo=None):
3558 self.foo = foo
3559 self.__foo = foo
3560 def setfoo(self, foo=None):
3561 self.foo = foo
3562 def getfoo(self):
3563 return self.__foo
3564 def __getstate__(self):
3565 return [self.foo]
3566 def __setstate__(self_, lst):
3567 self.assertEqual(len(lst), 1)
3568 self_.__foo = self_.foo = lst[0]
3569 a = C(42)
3570 a.setfoo(24)
3571 self.assertEqual(a.foo, 24)
3572 self.assertEqual(a.getfoo(), 42)
3573 b = copy.copy(a)
3574 self.assertEqual(b.foo, 24)
3575 self.assertEqual(b.getfoo(), 24)
3576 b = copy.deepcopy(a)
3577 self.assertEqual(b.foo, 24)
3578 self.assertEqual(b.getfoo(), 24)
3579
3580 def test_slices(self):
3581 # Testing cases with slices and overridden __getitem__ ...
3582
3583 # Strings
3584 self.assertEqual("hello"[:4], "hell")
3585 self.assertEqual("hello"[slice(4)], "hell")
3586 self.assertEqual(str.__getitem__("hello", slice(4)), "hell")
3587 class S(str):
3588 def __getitem__(self, x):
3589 return str.__getitem__(self, x)
3590 self.assertEqual(S("hello")[:4], "hell")
3591 self.assertEqual(S("hello")[slice(4)], "hell")
3592 self.assertEqual(S("hello").__getitem__(slice(4)), "hell")
3593 # Tuples
3594 self.assertEqual((1,2,3)[:2], (1,2))
3595 self.assertEqual((1,2,3)[slice(2)], (1,2))
3596 self.assertEqual(tuple.__getitem__((1,2,3), slice(2)), (1,2))
3597 class T(tuple):
3598 def __getitem__(self, x):
3599 return tuple.__getitem__(self, x)
3600 self.assertEqual(T((1,2,3))[:2], (1,2))
3601 self.assertEqual(T((1,2,3))[slice(2)], (1,2))
3602 self.assertEqual(T((1,2,3)).__getitem__(slice(2)), (1,2))
3603 # Lists
3604 self.assertEqual([1,2,3][:2], [1,2])
3605 self.assertEqual([1,2,3][slice(2)], [1,2])
3606 self.assertEqual(list.__getitem__([1,2,3], slice(2)), [1,2])
3607 class L(list):
3608 def __getitem__(self, x):
3609 return list.__getitem__(self, x)
3610 self.assertEqual(L([1,2,3])[:2], [1,2])
3611 self.assertEqual(L([1,2,3])[slice(2)], [1,2])
3612 self.assertEqual(L([1,2,3]).__getitem__(slice(2)), [1,2])
3613 # Now do lists and __setitem__
3614 a = L([1,2,3])
3615 a[slice(1, 3)] = [3,2]
3616 self.assertEqual(a, [1,3,2])
3617 a[slice(0, 2, 1)] = [3,1]
3618 self.assertEqual(a, [3,1,2])
3619 a.__setitem__(slice(1, 3), [2,1])
3620 self.assertEqual(a, [3,2,1])
3621 a.__setitem__(slice(0, 2, 1), [2,3])
3622 self.assertEqual(a, [2,3,1])
3623
3624 def test_subtype_resurrection(self):
3625 # Testing resurrection of new-style instance...
3626
3627 class C(object):
3628 container = []
3629
3630 def __del__(self):
3631 # resurrect the instance
3632 C.container.append(self)
3633
3634 c = C()
3635 c.attr = 42
3636
3637 # The most interesting thing here is whether this blows up, due to flawed
3638 # GC tracking logic in typeobject.c's call_finalizer() (a 2.2.1 bug).
3639 del c
3640
3641 # If that didn't blow up, it's also interesting to see whether clearing
3642 # the last container slot works: that will attempt to delete c again,
3643 # which will cause c to get appended back to the container again "during"
3644 # the del.
3645 del C.container[-1]
3646 self.assertEqual(len(C.container), 1)
3647 self.assertEqual(C.container[-1].attr, 42)
3648
3649 # Make c mortal again, so that the test framework with -l doesn't report
3650 # it as a leak.
3651 del C.__del__
3652
3653 def test_slots_trash(self):
3654 # Testing slot trash...
3655 # Deallocating deeply nested slotted trash caused stack overflows
3656 class trash(object):
3657 __slots__ = ['x']
3658 def __init__(self, x):
3659 self.x = x
3660 o = None
3661 for i in xrange(50000):
3662 o = trash(o)
3663 del o
3664
3665 def test_slots_multiple_inheritance(self):
3666 # SF bug 575229, multiple inheritance w/ slots dumps core
3667 class A(object):
3668 __slots__=()
3669 class B(object):
3670 pass
3671 class C(A,B) :
3672 __slots__=()
3673 self.assertEqual(C.__basicsize__, B.__basicsize__)
3674 self.assert_(hasattr(C, '__dict__'))
3675 self.assert_(hasattr(C, '__weakref__'))
3676 C().x = 2
3677
3678 def test_rmul(self):
3679 # Testing correct invocation of __rmul__...
3680 # SF patch 592646
3681 class C(object):
3682 def __mul__(self, other):
3683 return "mul"
3684 def __rmul__(self, other):
3685 return "rmul"
3686 a = C()
3687 self.assertEqual(a*2, "mul")
3688 self.assertEqual(a*2.2, "mul")
3689 self.assertEqual(2*a, "rmul")
3690 self.assertEqual(2.2*a, "rmul")
3691
3692 def test_ipow(self):
3693 # Testing correct invocation of __ipow__...
3694 # [SF bug 620179]
3695 class C(object):
3696 def __ipow__(self, other):
3697 pass
3698 a = C()
3699 a **= 2
3700
3701 def test_mutable_bases(self):
3702 # Testing mutable bases...
3703
3704 # stuff that should work:
3705 class C(object):
3706 pass
3707 class C2(object):
3708 def __getattribute__(self, attr):
3709 if attr == 'a':
3710 return 2
3711 else:
3712 return super(C2, self).__getattribute__(attr)
3713 def meth(self):
3714 return 1
3715 class D(C):
3716 pass
3717 class E(D):
3718 pass
3719 d = D()
3720 e = E()
3721 D.__bases__ = (C,)
3722 D.__bases__ = (C2,)
3723 self.assertEqual(d.meth(), 1)
3724 self.assertEqual(e.meth(), 1)
3725 self.assertEqual(d.a, 2)
3726 self.assertEqual(e.a, 2)
3727 self.assertEqual(C2.__subclasses__(), [D])
3728
3729 # stuff that shouldn't:
3730 class L(list):
3731 pass
3732
3733 try:
3734 L.__bases__ = (dict,)
3735 except TypeError:
3736 pass
3737 else:
3738 self.fail("shouldn't turn list subclass into dict subclass")
3739
3740 try:
3741 list.__bases__ = (dict,)
3742 except TypeError:
3743 pass
3744 else:
3745 self.fail("shouldn't be able to assign to list.__bases__")
3746
3747 try:
3748 D.__bases__ = (C2, list)
3749 except TypeError:
3750 pass
3751 else:
3752 assert 0, "best_base calculation found wanting"
3753
3754 try:
3755 del D.__bases__
3756 except TypeError:
3757 pass
3758 else:
3759 self.fail("shouldn't be able to delete .__bases__")
3760
3761 try:
3762 D.__bases__ = ()
3763 except TypeError, msg:
3764 if str(msg) == "a new-style class can't have only classic bases":
3765 self.fail("wrong error message for .__bases__ = ()")
3766 else:
3767 self.fail("shouldn't be able to set .__bases__ to ()")
3768
3769 try:
3770 D.__bases__ = (D,)
3771 except TypeError:
3772 pass
3773 else:
3774 # actually, we'll have crashed by here...
3775 self.fail("shouldn't be able to create inheritance cycles")
3776
3777 try:
3778 D.__bases__ = (C, C)
3779 except TypeError:
3780 pass
3781 else:
3782 self.fail("didn't detect repeated base classes")
3783
3784 try:
3785 D.__bases__ = (E,)
3786 except TypeError:
3787 pass
3788 else:
3789 self.fail("shouldn't be able to create inheritance cycles")
3790
3791 # let's throw a classic class into the mix:
3792 class Classic:
3793 def meth2(self):
3794 return 3
3795
3796 D.__bases__ = (C, Classic)
3797
3798 self.assertEqual(d.meth2(), 3)
3799 self.assertEqual(e.meth2(), 3)
3800 try:
3801 d.a
3802 except AttributeError:
3803 pass
3804 else:
3805 self.fail("attribute should have vanished")
3806
3807 try:
3808 D.__bases__ = (Classic,)
3809 except TypeError:
3810 pass
3811 else:
3812 self.fail("new-style class must have a new-style base")
3813
3814 def test_mutable_bases_with_failing_mro(self):
3815 # Testing mutable bases with failing mro...
3816 class WorkOnce(type):
3817 def __new__(self, name, bases, ns):
3818 self.flag = 0
3819 return super(WorkOnce, self).__new__(WorkOnce, name, bases, ns)
3820 def mro(self):
3821 if self.flag > 0:
3822 raise RuntimeError, "bozo"
3823 else:
3824 self.flag += 1
3825 return type.mro(self)
3826
3827 class WorkAlways(type):
3828 def mro(self):
3829 # this is here to make sure that .mro()s aren't called
3830 # with an exception set (which was possible at one point).
3831 # An error message will be printed in a debug build.
3832 # What's a good way to test for this?
Michael W. Hudson586da8f2002-11-27 15:20:19 +00003833 return type.mro(self)
3834
Georg Brandl48545522008-02-02 10:12:36 +00003835 class C(object):
3836 pass
Michael W. Hudson586da8f2002-11-27 15:20:19 +00003837
Georg Brandl48545522008-02-02 10:12:36 +00003838 class C2(object):
3839 pass
Michael W. Hudson586da8f2002-11-27 15:20:19 +00003840
Georg Brandl48545522008-02-02 10:12:36 +00003841 class D(C):
3842 pass
Michael W. Hudson586da8f2002-11-27 15:20:19 +00003843
Georg Brandl48545522008-02-02 10:12:36 +00003844 class E(D):
3845 pass
Michael W. Hudson586da8f2002-11-27 15:20:19 +00003846
Georg Brandl48545522008-02-02 10:12:36 +00003847 class F(D):
3848 __metaclass__ = WorkOnce
Michael W. Hudson586da8f2002-11-27 15:20:19 +00003849
Georg Brandl48545522008-02-02 10:12:36 +00003850 class G(D):
3851 __metaclass__ = WorkAlways
Michael W. Hudson586da8f2002-11-27 15:20:19 +00003852
Georg Brandl48545522008-02-02 10:12:36 +00003853 # Immediate subclasses have their mro's adjusted in alphabetical
3854 # order, so E's will get adjusted before adjusting F's fails. We
3855 # check here that E's gets restored.
Michael W. Hudson586da8f2002-11-27 15:20:19 +00003856
Georg Brandl48545522008-02-02 10:12:36 +00003857 E_mro_before = E.__mro__
3858 D_mro_before = D.__mro__
Armin Rigofd163f92005-12-29 15:59:19 +00003859
Armin Rigofd163f92005-12-29 15:59:19 +00003860 try:
Georg Brandl48545522008-02-02 10:12:36 +00003861 D.__bases__ = (C2,)
3862 except RuntimeError:
3863 self.assertEqual(E.__mro__, E_mro_before)
3864 self.assertEqual(D.__mro__, D_mro_before)
3865 else:
3866 self.fail("exception not propagated")
3867
3868 def test_mutable_bases_catch_mro_conflict(self):
3869 # Testing mutable bases catch mro conflict...
3870 class A(object):
3871 pass
3872
3873 class B(object):
3874 pass
3875
3876 class C(A, B):
3877 pass
3878
3879 class D(A, B):
3880 pass
3881
3882 class E(C, D):
3883 pass
3884
3885 try:
3886 C.__bases__ = (B, A)
Armin Rigofd163f92005-12-29 15:59:19 +00003887 except TypeError:
3888 pass
3889 else:
Georg Brandl48545522008-02-02 10:12:36 +00003890 self.fail("didn't catch MRO conflict")
Armin Rigofd163f92005-12-29 15:59:19 +00003891
Georg Brandl48545522008-02-02 10:12:36 +00003892 def test_mutable_names(self):
3893 # Testing mutable names...
3894 class C(object):
3895 pass
3896
3897 # C.__module__ could be 'test_descr' or '__main__'
3898 mod = C.__module__
3899
3900 C.__name__ = 'D'
3901 self.assertEqual((C.__module__, C.__name__), (mod, 'D'))
3902
3903 C.__name__ = 'D.E'
3904 self.assertEqual((C.__module__, C.__name__), (mod, 'D.E'))
3905
3906 def test_subclass_right_op(self):
3907 # Testing correct dispatch of subclass overloading __r<op>__...
3908
3909 # This code tests various cases where right-dispatch of a subclass
3910 # should be preferred over left-dispatch of a base class.
3911
3912 # Case 1: subclass of int; this tests code in abstract.c::binary_op1()
3913
3914 class B(int):
3915 def __floordiv__(self, other):
3916 return "B.__floordiv__"
3917 def __rfloordiv__(self, other):
3918 return "B.__rfloordiv__"
3919
3920 self.assertEqual(B(1) // 1, "B.__floordiv__")
3921 self.assertEqual(1 // B(1), "B.__rfloordiv__")
3922
3923 # Case 2: subclass of object; this is just the baseline for case 3
3924
3925 class C(object):
3926 def __floordiv__(self, other):
3927 return "C.__floordiv__"
3928 def __rfloordiv__(self, other):
3929 return "C.__rfloordiv__"
3930
3931 self.assertEqual(C() // 1, "C.__floordiv__")
3932 self.assertEqual(1 // C(), "C.__rfloordiv__")
3933
3934 # Case 3: subclass of new-style class; here it gets interesting
3935
3936 class D(C):
3937 def __floordiv__(self, other):
3938 return "D.__floordiv__"
3939 def __rfloordiv__(self, other):
3940 return "D.__rfloordiv__"
3941
3942 self.assertEqual(D() // C(), "D.__floordiv__")
3943 self.assertEqual(C() // D(), "D.__rfloordiv__")
3944
3945 # Case 4: this didn't work right in 2.2.2 and 2.3a1
3946
3947 class E(C):
3948 pass
3949
3950 self.assertEqual(E.__rfloordiv__, C.__rfloordiv__)
3951
3952 self.assertEqual(E() // 1, "C.__floordiv__")
3953 self.assertEqual(1 // E(), "C.__rfloordiv__")
3954 self.assertEqual(E() // C(), "C.__floordiv__")
3955 self.assertEqual(C() // E(), "C.__floordiv__") # This one would fail
3956
3957 def test_meth_class_get(self):
3958 # Testing __get__ method of METH_CLASS C methods...
3959 # Full coverage of descrobject.c::classmethod_get()
3960
3961 # Baseline
3962 arg = [1, 2, 3]
3963 res = {1: None, 2: None, 3: None}
3964 self.assertEqual(dict.fromkeys(arg), res)
3965 self.assertEqual({}.fromkeys(arg), res)
3966
3967 # Now get the descriptor
3968 descr = dict.__dict__["fromkeys"]
3969
3970 # More baseline using the descriptor directly
3971 self.assertEqual(descr.__get__(None, dict)(arg), res)
3972 self.assertEqual(descr.__get__({})(arg), res)
3973
3974 # Now check various error cases
3975 try:
3976 descr.__get__(None, None)
3977 except TypeError:
3978 pass
3979 else:
3980 self.fail("shouldn't have allowed descr.__get__(None, None)")
3981 try:
3982 descr.__get__(42)
3983 except TypeError:
3984 pass
3985 else:
3986 self.fail("shouldn't have allowed descr.__get__(42)")
3987 try:
3988 descr.__get__(None, 42)
3989 except TypeError:
3990 pass
3991 else:
3992 self.fail("shouldn't have allowed descr.__get__(None, 42)")
3993 try:
3994 descr.__get__(None, int)
3995 except TypeError:
3996 pass
3997 else:
3998 self.fail("shouldn't have allowed descr.__get__(None, int)")
3999
4000 def test_isinst_isclass(self):
4001 # Testing proxy isinstance() and isclass()...
4002 class Proxy(object):
4003 def __init__(self, obj):
4004 self.__obj = obj
4005 def __getattribute__(self, name):
4006 if name.startswith("_Proxy__"):
4007 return object.__getattribute__(self, name)
4008 else:
4009 return getattr(self.__obj, name)
4010 # Test with a classic class
4011 class C:
4012 pass
4013 a = C()
4014 pa = Proxy(a)
4015 self.assert_(isinstance(a, C)) # Baseline
4016 self.assert_(isinstance(pa, C)) # Test
4017 # Test with a classic subclass
4018 class D(C):
4019 pass
4020 a = D()
4021 pa = Proxy(a)
4022 self.assert_(isinstance(a, C)) # Baseline
4023 self.assert_(isinstance(pa, C)) # Test
4024 # Test with a new-style class
4025 class C(object):
4026 pass
4027 a = C()
4028 pa = Proxy(a)
4029 self.assert_(isinstance(a, C)) # Baseline
4030 self.assert_(isinstance(pa, C)) # Test
4031 # Test with a new-style subclass
4032 class D(C):
4033 pass
4034 a = D()
4035 pa = Proxy(a)
4036 self.assert_(isinstance(a, C)) # Baseline
4037 self.assert_(isinstance(pa, C)) # Test
4038
4039 def test_proxy_super(self):
4040 # Testing super() for a proxy object...
4041 class Proxy(object):
4042 def __init__(self, obj):
4043 self.__obj = obj
4044 def __getattribute__(self, name):
4045 if name.startswith("_Proxy__"):
4046 return object.__getattribute__(self, name)
4047 else:
4048 return getattr(self.__obj, name)
4049
4050 class B(object):
4051 def f(self):
4052 return "B.f"
4053
4054 class C(B):
4055 def f(self):
4056 return super(C, self).f() + "->C.f"
4057
4058 obj = C()
4059 p = Proxy(obj)
4060 self.assertEqual(C.__dict__["f"](p), "B.f->C.f")
4061
4062 def test_carloverre(self):
4063 # Testing prohibition of Carlo Verre's hack...
4064 try:
4065 object.__setattr__(str, "foo", 42)
4066 except TypeError:
4067 pass
4068 else:
4069 self.fail("Carlo Verre __setattr__ suceeded!")
4070 try:
4071 object.__delattr__(str, "lower")
4072 except TypeError:
4073 pass
4074 else:
4075 self.fail("Carlo Verre __delattr__ succeeded!")
4076
4077 def test_weakref_segfault(self):
4078 # Testing weakref segfault...
4079 # SF 742911
4080 import weakref
4081
4082 class Provoker:
4083 def __init__(self, referrent):
4084 self.ref = weakref.ref(referrent)
4085
4086 def __del__(self):
4087 x = self.ref()
4088
4089 class Oops(object):
4090 pass
4091
4092 o = Oops()
4093 o.whatever = Provoker(o)
4094 del o
4095
4096 def test_wrapper_segfault(self):
4097 # SF 927248: deeply nested wrappers could cause stack overflow
4098 f = lambda:None
4099 for i in xrange(1000000):
4100 f = f.__call__
4101 f = None
4102
4103 def test_file_fault(self):
4104 # Testing sys.stdout is changed in getattr...
4105 import sys
4106 class StdoutGuard:
4107 def __getattr__(self, attr):
4108 sys.stdout = sys.__stdout__
4109 raise RuntimeError("Premature access to sys.stdout.%s" % attr)
4110 sys.stdout = StdoutGuard()
4111 try:
4112 print "Oops!"
4113 except RuntimeError:
4114 pass
4115
4116 def test_vicious_descriptor_nonsense(self):
4117 # Testing vicious_descriptor_nonsense...
4118
4119 # A potential segfault spotted by Thomas Wouters in mail to
4120 # python-dev 2003-04-17, turned into an example & fixed by Michael
4121 # Hudson just less than four months later...
4122
4123 class Evil(object):
4124 def __hash__(self):
4125 return hash('attr')
4126 def __eq__(self, other):
4127 del C.attr
4128 return 0
4129
4130 class Descr(object):
4131 def __get__(self, ob, type=None):
4132 return 1
4133
4134 class C(object):
4135 attr = Descr()
4136
4137 c = C()
4138 c.__dict__[Evil()] = 0
4139
4140 self.assertEqual(c.attr, 1)
4141 # this makes a crash more likely:
4142 import gc; gc.collect()
4143 self.assertEqual(hasattr(c, 'attr'), False)
4144
4145 def test_init(self):
4146 # SF 1155938
4147 class Foo(object):
4148 def __init__(self):
4149 return 10
4150 try:
4151 Foo()
4152 except TypeError:
4153 pass
4154 else:
4155 self.fail("did not test __init__() for None return")
4156
4157 def test_method_wrapper(self):
4158 # Testing method-wrapper objects...
4159 # <type 'method-wrapper'> did not support any reflection before 2.5
4160
4161 l = []
4162 self.assertEqual(l.__add__, l.__add__)
4163 self.assertEqual(l.__add__, [].__add__)
4164 self.assert_(l.__add__ != [5].__add__)
4165 self.assert_(l.__add__ != l.__mul__)
4166 self.assert_(l.__add__.__name__ == '__add__')
4167 self.assert_(l.__add__.__self__ is l)
4168 self.assert_(l.__add__.__objclass__ is list)
4169 self.assertEqual(l.__add__.__doc__, list.__add__.__doc__)
4170 try:
4171 hash(l.__add__)
4172 except TypeError:
4173 pass
4174 else:
4175 self.fail("no TypeError from hash([].__add__)")
4176
4177 t = ()
4178 t += (7,)
4179 self.assertEqual(t.__add__, (7,).__add__)
4180 self.assertEqual(hash(t.__add__), hash((7,).__add__))
4181
4182 def test_not_implemented(self):
4183 # Testing NotImplemented...
4184 # all binary methods should be able to return a NotImplemented
4185 import sys
4186 import types
4187 import operator
4188
4189 def specialmethod(self, other):
4190 return NotImplemented
4191
4192 def check(expr, x, y):
4193 try:
4194 exec expr in {'x': x, 'y': y, 'operator': operator}
4195 except TypeError:
4196 pass
Armin Rigofd163f92005-12-29 15:59:19 +00004197 else:
Georg Brandl48545522008-02-02 10:12:36 +00004198 self.fail("no TypeError from %r" % (expr,))
Armin Rigofd163f92005-12-29 15:59:19 +00004199
Georg Brandl48545522008-02-02 10:12:36 +00004200 N1 = sys.maxint + 1L # might trigger OverflowErrors instead of
4201 # TypeErrors
4202 N2 = sys.maxint # if sizeof(int) < sizeof(long), might trigger
4203 # ValueErrors instead of TypeErrors
4204 for metaclass in [type, types.ClassType]:
4205 for name, expr, iexpr in [
4206 ('__add__', 'x + y', 'x += y'),
4207 ('__sub__', 'x - y', 'x -= y'),
4208 ('__mul__', 'x * y', 'x *= y'),
4209 ('__truediv__', 'operator.truediv(x, y)', None),
4210 ('__floordiv__', 'operator.floordiv(x, y)', None),
4211 ('__div__', 'x / y', 'x /= y'),
4212 ('__mod__', 'x % y', 'x %= y'),
4213 ('__divmod__', 'divmod(x, y)', None),
4214 ('__pow__', 'x ** y', 'x **= y'),
4215 ('__lshift__', 'x << y', 'x <<= y'),
4216 ('__rshift__', 'x >> y', 'x >>= y'),
4217 ('__and__', 'x & y', 'x &= y'),
4218 ('__or__', 'x | y', 'x |= y'),
4219 ('__xor__', 'x ^ y', 'x ^= y'),
4220 ('__coerce__', 'coerce(x, y)', None)]:
4221 if name == '__coerce__':
4222 rname = name
4223 else:
4224 rname = '__r' + name[2:]
4225 A = metaclass('A', (), {name: specialmethod})
4226 B = metaclass('B', (), {rname: specialmethod})
4227 a = A()
4228 b = B()
4229 check(expr, a, a)
4230 check(expr, a, b)
4231 check(expr, b, a)
4232 check(expr, b, b)
4233 check(expr, a, N1)
4234 check(expr, a, N2)
4235 check(expr, N1, b)
4236 check(expr, N2, b)
4237 if iexpr:
4238 check(iexpr, a, a)
4239 check(iexpr, a, b)
4240 check(iexpr, b, a)
4241 check(iexpr, b, b)
4242 check(iexpr, a, N1)
4243 check(iexpr, a, N2)
4244 iname = '__i' + name[2:]
4245 C = metaclass('C', (), {iname: specialmethod})
4246 c = C()
4247 check(iexpr, c, a)
4248 check(iexpr, c, b)
4249 check(iexpr, c, N1)
4250 check(iexpr, c, N2)
Georg Brandl0fca97a2007-03-05 22:28:08 +00004251
Georg Brandl48545522008-02-02 10:12:36 +00004252 def test_assign_slice(self):
4253 # ceval.c's assign_slice used to check for
4254 # tp->tp_as_sequence->sq_slice instead of
4255 # tp->tp_as_sequence->sq_ass_slice
Georg Brandl0fca97a2007-03-05 22:28:08 +00004256
Georg Brandl48545522008-02-02 10:12:36 +00004257 class C(object):
4258 def __setslice__(self, start, stop, value):
4259 self.value = value
Georg Brandl0fca97a2007-03-05 22:28:08 +00004260
Georg Brandl48545522008-02-02 10:12:36 +00004261 c = C()
4262 c[1:2] = 3
4263 self.assertEqual(c.value, 3)
Guido van Rossum9acc3872008-01-23 23:23:43 +00004264
Guido van Rossum9acc3872008-01-23 23:23:43 +00004265
Georg Brandl48545522008-02-02 10:12:36 +00004266class DictProxyTests(unittest.TestCase):
4267 def setUp(self):
4268 class C(object):
4269 def meth(self):
4270 pass
4271 self.C = C
Guido van Rossum9acc3872008-01-23 23:23:43 +00004272
Georg Brandl48545522008-02-02 10:12:36 +00004273 def test_iter_keys(self):
4274 # Testing dict-proxy iterkeys...
4275 keys = [ key for key in self.C.__dict__.iterkeys() ]
4276 keys.sort()
4277 self.assertEquals(keys, ['__dict__', '__doc__', '__module__',
4278 '__weakref__', 'meth'])
Guido van Rossum9acc3872008-01-23 23:23:43 +00004279
Georg Brandl48545522008-02-02 10:12:36 +00004280 def test_iter_values(self):
4281 # Testing dict-proxy itervalues...
4282 values = [ values for values in self.C.__dict__.itervalues() ]
4283 self.assertEqual(len(values), 5)
Guido van Rossum9acc3872008-01-23 23:23:43 +00004284
Georg Brandl48545522008-02-02 10:12:36 +00004285 def test_iter_items(self):
4286 # Testing dict-proxy iteritems...
4287 keys = [ key for (key, value) in self.C.__dict__.iteritems() ]
4288 keys.sort()
4289 self.assertEqual(keys, ['__dict__', '__doc__', '__module__',
4290 '__weakref__', 'meth'])
Guido van Rossum9acc3872008-01-23 23:23:43 +00004291
Georg Brandl48545522008-02-02 10:12:36 +00004292 def test_dict_type_with_metaclass(self):
4293 # Testing type of __dict__ when __metaclass__ set...
4294 class B(object):
4295 pass
4296 class M(type):
4297 pass
4298 class C:
4299 # In 2.3a1, C.__dict__ was a real dict rather than a dict proxy
4300 __metaclass__ = M
4301 self.assertEqual(type(C.__dict__), type(B.__dict__))
Guido van Rossum9acc3872008-01-23 23:23:43 +00004302
Guido van Rossum9acc3872008-01-23 23:23:43 +00004303
Georg Brandl48545522008-02-02 10:12:36 +00004304class PTypesLongInitTest(unittest.TestCase):
4305 # This is in its own TestCase so that it can be run before any other tests.
4306 def test_pytype_long_ready(self):
4307 # Testing SF bug 551412 ...
Guido van Rossum9acc3872008-01-23 23:23:43 +00004308
Georg Brandl48545522008-02-02 10:12:36 +00004309 # This dumps core when SF bug 551412 isn't fixed --
4310 # but only when test_descr.py is run separately.
4311 # (That can't be helped -- as soon as PyType_Ready()
4312 # is called for PyLong_Type, the bug is gone.)
4313 class UserLong(object):
4314 def __pow__(self, *args):
4315 pass
4316 try:
4317 pow(0L, UserLong(), 0L)
4318 except:
4319 pass
Guido van Rossum9acc3872008-01-23 23:23:43 +00004320
Georg Brandl48545522008-02-02 10:12:36 +00004321 # Another segfault only when run early
4322 # (before PyType_Ready(tuple) is called)
4323 type.mro(tuple)
Guido van Rossum37edeab2008-01-24 17:58:05 +00004324
4325
Guido van Rossuma56b42b2001-09-20 21:39:07 +00004326def test_main():
Georg Brandl48545522008-02-02 10:12:36 +00004327 # Run all local test cases, with PTypesLongInitTest first.
4328 test_support.run_unittest(PTypesLongInitTest, OperatorsTest,
4329 ClassPropertiesAndMethods, DictProxyTests)
Tim Peters6d6c1a32001-08-02 04:15:00 +00004330
Guido van Rossuma56b42b2001-09-20 21:39:07 +00004331if __name__ == "__main__":
4332 test_main()