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