Merged release21-maint changes.
[python/dscho.git] / Lib / test / test_descr.py
blob737fce9b719773034fd7835969f673c247f0fe3a
1 # Test descriptor-related enhancements
3 from test_support import verify, verbose
4 from copy import deepcopy
6 def testunop(a, res, expr="len(a)", meth="__len__"):
7 if verbose: print "checking", expr
8 dict = {'a': a}
9 verify(eval(expr, dict) == res)
10 t = type(a)
11 m = getattr(t, meth)
12 verify(m == t.__dict__[meth])
13 verify(m(a) == res)
14 bm = getattr(a, meth)
15 verify(bm() == res)
17 def testbinop(a, b, res, expr="a+b", meth="__add__"):
18 if verbose: print "checking", expr
19 dict = {'a': a, 'b': b}
20 verify(eval(expr, dict) == res)
21 t = type(a)
22 m = getattr(t, meth)
23 verify(m == t.__dict__[meth])
24 verify(m(a, b) == res)
25 bm = getattr(a, meth)
26 verify(bm(b) == res)
28 def testternop(a, b, c, res, expr="a[b:c]", meth="__getslice__"):
29 if verbose: print "checking", expr
30 dict = {'a': a, 'b': b, 'c': c}
31 verify(eval(expr, dict) == res)
32 t = type(a)
33 m = getattr(t, meth)
34 verify(m == t.__dict__[meth])
35 verify(m(a, b, c) == res)
36 bm = getattr(a, meth)
37 verify(bm(b, c) == res)
39 def testsetop(a, b, res, stmt="a+=b", meth="__iadd__"):
40 if verbose: print "checking", stmt
41 dict = {'a': deepcopy(a), 'b': b}
42 exec stmt in dict
43 verify(dict['a'] == res)
44 t = type(a)
45 m = getattr(t, meth)
46 verify(m == t.__dict__[meth])
47 dict['a'] = deepcopy(a)
48 m(dict['a'], b)
49 verify(dict['a'] == res)
50 dict['a'] = deepcopy(a)
51 bm = getattr(dict['a'], meth)
52 bm(b)
53 verify(dict['a'] == res)
55 def testset2op(a, b, c, res, stmt="a[b]=c", meth="__setitem__"):
56 if verbose: print "checking", stmt
57 dict = {'a': deepcopy(a), 'b': b, 'c': c}
58 exec stmt in dict
59 verify(dict['a'] == res)
60 t = type(a)
61 m = getattr(t, meth)
62 verify(m == t.__dict__[meth])
63 dict['a'] = deepcopy(a)
64 m(dict['a'], b, c)
65 verify(dict['a'] == res)
66 dict['a'] = deepcopy(a)
67 bm = getattr(dict['a'], meth)
68 bm(b, c)
69 verify(dict['a'] == res)
71 def testset3op(a, b, c, d, res, stmt="a[b:c]=d", meth="__setslice__"):
72 if verbose: print "checking", stmt
73 dict = {'a': deepcopy(a), 'b': b, 'c': c, 'd': d}
74 exec stmt in dict
75 verify(dict['a'] == res)
76 t = type(a)
77 m = getattr(t, meth)
78 verify(m == t.__dict__[meth])
79 dict['a'] = deepcopy(a)
80 m(dict['a'], b, c, d)
81 verify(dict['a'] == res)
82 dict['a'] = deepcopy(a)
83 bm = getattr(dict['a'], meth)
84 bm(b, c, d)
85 verify(dict['a'] == res)
87 def lists():
88 if verbose: print "Testing list operations..."
89 testbinop([1], [2], [1,2], "a+b", "__add__")
90 testbinop([1,2,3], 2, 1, "b in a", "__contains__")
91 testbinop([1,2,3], 4, 0, "b in a", "__contains__")
92 testbinop([1,2,3], 1, 2, "a[b]", "__getitem__")
93 testternop([1,2,3], 0, 2, [1,2], "a[b:c]", "__getslice__")
94 testsetop([1], [2], [1,2], "a+=b", "__iadd__")
95 testsetop([1,2], 3, [1,2,1,2,1,2], "a*=b", "__imul__")
96 testunop([1,2,3], 3, "len(a)", "__len__")
97 testbinop([1,2], 3, [1,2,1,2,1,2], "a*b", "__mul__")
98 testbinop([1,2], 3, [1,2,1,2,1,2], "b*a", "__rmul__")
99 testset2op([1,2], 1, 3, [1,3], "a[b]=c", "__setitem__")
100 testset3op([1,2,3,4], 1, 3, [5,6], [1,5,6,4], "a[b:c]=d", "__setslice__")
102 def dicts():
103 if verbose: print "Testing dict operations..."
104 testbinop({1:2}, {2:1}, -1, "cmp(a,b)", "__cmp__")
105 testbinop({1:2,3:4}, 1, 1, "b in a", "__contains__")
106 testbinop({1:2,3:4}, 2, 0, "b in a", "__contains__")
107 testbinop({1:2,3:4}, 1, 2, "a[b]", "__getitem__")
108 d = {1:2,3:4}
109 l1 = []
110 for i in d.keys(): l1.append(i)
111 l = []
112 for i in iter(d): l.append(i)
113 verify(l == l1)
114 l = []
115 for i in d.__iter__(): l.append(i)
116 verify(l == l1)
117 l = []
118 for i in dictionary.__iter__(d): l.append(i)
119 verify(l == l1)
120 d = {1:2, 3:4}
121 testunop(d, 2, "len(a)", "__len__")
122 verify(eval(repr(d), {}) == d)
123 verify(eval(d.__repr__(), {}) == d)
124 testset2op({1:2,3:4}, 2, 3, {1:2,2:3,3:4}, "a[b]=c", "__setitem__")
126 binops = {
127 'add': '+',
128 'sub': '-',
129 'mul': '*',
130 'div': '/',
131 'mod': '%',
132 'divmod': 'divmod',
133 'pow': '**',
134 'lshift': '<<',
135 'rshift': '>>',
136 'and': '&',
137 'xor': '^',
138 'or': '|',
139 'cmp': 'cmp',
140 'lt': '<',
141 'le': '<=',
142 'eq': '==',
143 'ne': '!=',
144 'gt': '>',
145 'ge': '>=',
148 for name, expr in binops.items():
149 if expr.islower():
150 expr = expr + "(a, b)"
151 else:
152 expr = 'a %s b' % expr
153 binops[name] = expr
155 unops = {
156 'pos': '+',
157 'neg': '-',
158 'abs': 'abs',
159 'invert': '~',
160 'int': 'int',
161 'long': 'long',
162 'float': 'float',
163 'oct': 'oct',
164 'hex': 'hex',
167 for name, expr in unops.items():
168 if expr.islower():
169 expr = expr + "(a)"
170 else:
171 expr = '%s a' % expr
172 unops[name] = expr
174 def numops(a, b, skip=[]):
175 dict = {'a': a, 'b': b}
176 for name, expr in binops.items():
177 if name not in skip:
178 name = "__%s__" % name
179 if hasattr(a, name):
180 res = eval(expr, dict)
181 testbinop(a, b, res, expr, name)
182 for name, expr in unops.items():
183 name = "__%s__" % name
184 if hasattr(a, name):
185 res = eval(expr, dict)
186 testunop(a, res, expr, name)
188 def ints():
189 if verbose: print "Testing int operations..."
190 numops(100, 3)
192 def longs():
193 if verbose: print "Testing long operations..."
194 numops(100L, 3L)
196 def floats():
197 if verbose: print "Testing float operations..."
198 numops(100.0, 3.0)
200 def complexes():
201 if verbose: print "Testing complex operations..."
202 numops(100.0j, 3.0j, skip=['lt', 'le', 'gt', 'ge'])
203 class Number(complex):
204 __slots__ = ['prec']
205 def __init__(self, *args, **kwds):
206 self.prec = kwds.get('prec', 12)
207 def __repr__(self):
208 prec = self.prec
209 if self.imag == 0.0:
210 return "%.*g" % (prec, self.real)
211 if self.real == 0.0:
212 return "%.*gj" % (prec, self.imag)
213 return "(%.*g+%.*gj)" % (prec, self.real, prec, self.imag)
214 __str__ = __repr__
215 a = Number(3.14, prec=6)
216 verify(`a` == "3.14")
217 verify(a.prec == 6)
219 def spamlists():
220 if verbose: print "Testing spamlist operations..."
221 import copy, xxsubtype as spam
222 def spamlist(l, memo=None):
223 import xxsubtype as spam
224 return spam.spamlist(l)
225 # This is an ugly hack:
226 copy._deepcopy_dispatch[spam.spamlist] = spamlist
228 testbinop(spamlist([1]), spamlist([2]), spamlist([1,2]), "a+b", "__add__")
229 testbinop(spamlist([1,2,3]), 2, 1, "b in a", "__contains__")
230 testbinop(spamlist([1,2,3]), 4, 0, "b in a", "__contains__")
231 testbinop(spamlist([1,2,3]), 1, 2, "a[b]", "__getitem__")
232 testternop(spamlist([1,2,3]), 0, 2, spamlist([1,2]),
233 "a[b:c]", "__getslice__")
234 testsetop(spamlist([1]), spamlist([2]), spamlist([1,2]),
235 "a+=b", "__iadd__")
236 testsetop(spamlist([1,2]), 3, spamlist([1,2,1,2,1,2]), "a*=b", "__imul__")
237 testunop(spamlist([1,2,3]), 3, "len(a)", "__len__")
238 testbinop(spamlist([1,2]), 3, spamlist([1,2,1,2,1,2]), "a*b", "__mul__")
239 testbinop(spamlist([1,2]), 3, spamlist([1,2,1,2,1,2]), "b*a", "__rmul__")
240 testset2op(spamlist([1,2]), 1, 3, spamlist([1,3]), "a[b]=c", "__setitem__")
241 testset3op(spamlist([1,2,3,4]), 1, 3, spamlist([5,6]),
242 spamlist([1,5,6,4]), "a[b:c]=d", "__setslice__")
243 # Test subclassing
244 class C(spam.spamlist):
245 def foo(self): return 1
246 a = C()
247 verify(a == [])
248 verify(a.foo() == 1)
249 a.append(100)
250 verify(a == [100])
251 verify(a.getstate() == 0)
252 a.setstate(42)
253 verify(a.getstate() == 42)
255 def spamdicts():
256 if verbose: print "Testing spamdict operations..."
257 import copy, xxsubtype as spam
258 def spamdict(d, memo=None):
259 import xxsubtype as spam
260 sd = spam.spamdict()
261 for k, v in d.items(): sd[k] = v
262 return sd
263 # This is an ugly hack:
264 copy._deepcopy_dispatch[spam.spamdict] = spamdict
266 testbinop(spamdict({1:2}), spamdict({2:1}), -1, "cmp(a,b)", "__cmp__")
267 testbinop(spamdict({1:2,3:4}), 1, 1, "b in a", "__contains__")
268 testbinop(spamdict({1:2,3:4}), 2, 0, "b in a", "__contains__")
269 testbinop(spamdict({1:2,3:4}), 1, 2, "a[b]", "__getitem__")
270 d = spamdict({1:2,3:4})
271 l1 = []
272 for i in d.keys(): l1.append(i)
273 l = []
274 for i in iter(d): l.append(i)
275 verify(l == l1)
276 l = []
277 for i in d.__iter__(): l.append(i)
278 verify(l == l1)
279 l = []
280 for i in type(spamdict({})).__iter__(d): l.append(i)
281 verify(l == l1)
282 straightd = {1:2, 3:4}
283 spamd = spamdict(straightd)
284 testunop(spamd, 2, "len(a)", "__len__")
285 testunop(spamd, repr(straightd), "repr(a)", "__repr__")
286 testset2op(spamdict({1:2,3:4}), 2, 3, spamdict({1:2,2:3,3:4}),
287 "a[b]=c", "__setitem__")
288 # Test subclassing
289 class C(spam.spamdict):
290 def foo(self): return 1
291 a = C()
292 verify(a.items() == [])
293 verify(a.foo() == 1)
294 a['foo'] = 'bar'
295 verify(a.items() == [('foo', 'bar')])
296 verify(a.getstate() == 0)
297 a.setstate(100)
298 verify(a.getstate() == 100)
300 def pydicts():
301 if verbose: print "Testing Python subclass of dict..."
302 verify(issubclass(dictionary, dictionary))
303 verify(isinstance({}, dictionary))
304 d = dictionary()
305 verify(d == {})
306 verify(d.__class__ is dictionary)
307 verify(isinstance(d, dictionary))
308 class C(dictionary):
309 state = -1
310 def __init__(self, *a, **kw):
311 if a:
312 assert len(a) == 1
313 self.state = a[0]
314 if kw:
315 for k, v in kw.items(): self[v] = k
316 def __getitem__(self, key):
317 return self.get(key, 0)
318 def __setitem__(self, key, value):
319 assert isinstance(key, type(0))
320 dictionary.__setitem__(self, key, value)
321 def setstate(self, state):
322 self.state = state
323 def getstate(self):
324 return self.state
325 verify(issubclass(C, dictionary))
326 a1 = C(12)
327 verify(a1.state == 12)
328 a2 = C(foo=1, bar=2)
329 verify(a2[1] == 'foo' and a2[2] == 'bar')
330 a = C()
331 verify(a.state == -1)
332 verify(a.getstate() == -1)
333 a.setstate(0)
334 verify(a.state == 0)
335 verify(a.getstate() == 0)
336 a.setstate(10)
337 verify(a.state == 10)
338 verify(a.getstate() == 10)
339 verify(a[42] == 0)
340 a[42] = 24
341 verify(a[42] == 24)
342 if verbose: print "pydict stress test ..."
343 N = 50
344 for i in range(N):
345 a[i] = C()
346 for j in range(N):
347 a[i][j] = i*j
348 for i in range(N):
349 for j in range(N):
350 verify(a[i][j] == i*j)
352 def pylists():
353 if verbose: print "Testing Python subclass of list..."
354 class C(list):
355 def __getitem__(self, i):
356 return list.__getitem__(self, i) + 100
357 def __getslice__(self, i, j):
358 return (i, j)
359 a = C()
360 a.extend([0,1,2])
361 verify(a[0] == 100)
362 verify(a[1] == 101)
363 verify(a[2] == 102)
364 verify(a[100:200] == (100,200))
366 def metaclass():
367 if verbose: print "Testing __metaclass__..."
368 global C
369 class C:
370 __metaclass__ = type
371 def __init__(self):
372 self.__state = 0
373 def getstate(self):
374 return self.__state
375 def setstate(self, state):
376 self.__state = state
377 a = C()
378 verify(a.getstate() == 0)
379 a.setstate(10)
380 verify(a.getstate() == 10)
381 class D:
382 class __metaclass__(type):
383 def myself(cls): return cls
384 verify(D.myself() == D)
386 import sys
387 MT = type(sys)
389 def pymods():
390 if verbose: print "Testing Python subclass of module..."
391 global log
392 log = []
393 class MM(MT):
394 def __init__(self):
395 MT.__init__(self)
396 def __getattr__(self, name):
397 log.append(("getattr", name))
398 return MT.__getattr__(self, name)
399 def __setattr__(self, name, value):
400 log.append(("setattr", name, value))
401 MT.__setattr__(self, name, value)
402 def __delattr__(self, name):
403 log.append(("delattr", name))
404 MT.__delattr__(self, name)
405 a = MM()
406 a.foo = 12
407 x = a.foo
408 del a.foo
409 verify(log == [('getattr', '__init__'),
410 ('getattr', '__setattr__'),
411 ("setattr", "foo", 12),
412 ("getattr", "foo"),
413 ('getattr', '__delattr__'),
414 ("delattr", "foo")], log)
416 def multi():
417 if verbose: print "Testing multiple inheritance..."
418 global C
419 class C(object):
420 def __init__(self):
421 self.__state = 0
422 def getstate(self):
423 return self.__state
424 def setstate(self, state):
425 self.__state = state
426 a = C()
427 verify(a.getstate() == 0)
428 a.setstate(10)
429 verify(a.getstate() == 10)
430 class D(dictionary, C):
431 def __init__(self):
432 type({}).__init__(self)
433 C.__init__(self)
434 d = D()
435 verify(d.keys() == [])
436 d["hello"] = "world"
437 verify(d.items() == [("hello", "world")])
438 verify(d["hello"] == "world")
439 verify(d.getstate() == 0)
440 d.setstate(10)
441 verify(d.getstate() == 10)
442 verify(D.__mro__ == (D, dictionary, C, object))
444 # SF bug #442833
445 class Node(object):
446 def __int__(self):
447 return int(self.foo())
448 def foo(self):
449 return "23"
450 class Frag(Node, list):
451 def foo(self):
452 return "42"
453 verify(Node().__int__() == 23)
454 verify(int(Node()) == 23)
455 verify(Frag().__int__() == 42)
456 verify(int(Frag()) == 42)
458 def diamond():
459 if verbose: print "Testing multiple inheritance special cases..."
460 class A(object):
461 def spam(self): return "A"
462 verify(A().spam() == "A")
463 class B(A):
464 def boo(self): return "B"
465 def spam(self): return "B"
466 verify(B().spam() == "B")
467 verify(B().boo() == "B")
468 class C(A):
469 def boo(self): return "C"
470 verify(C().spam() == "A")
471 verify(C().boo() == "C")
472 class D(B, C): pass
473 verify(D().spam() == "B")
474 verify(D().boo() == "B")
475 verify(D.__mro__ == (D, B, C, A, object))
476 class E(C, B): pass
477 verify(E().spam() == "B")
478 verify(E().boo() == "C")
479 verify(E.__mro__ == (E, C, B, A, object))
480 class F(D, E): pass
481 verify(F().spam() == "B")
482 verify(F().boo() == "B")
483 verify(F.__mro__ == (F, D, E, B, C, A, object))
484 class G(E, D): pass
485 verify(G().spam() == "B")
486 verify(G().boo() == "C")
487 verify(G.__mro__ == (G, E, D, C, B, A, object))
489 def objects():
490 if verbose: print "Testing object class..."
491 a = object()
492 verify(a.__class__ == object == type(a))
493 b = object()
494 verify(a is not b)
495 verify(not hasattr(a, "foo"))
496 try:
497 a.foo = 12
498 except (AttributeError, TypeError):
499 pass
500 else:
501 verify(0, "object() should not allow setting a foo attribute")
502 verify(not hasattr(object(), "__dict__"))
504 class Cdict(object):
505 pass
506 x = Cdict()
507 verify(x.__dict__ is None)
508 x.foo = 1
509 verify(x.foo == 1)
510 verify(x.__dict__ == {'foo': 1})
512 def slots():
513 if verbose: print "Testing __slots__..."
514 class C0(object):
515 __slots__ = []
516 x = C0()
517 verify(not hasattr(x, "__dict__"))
518 verify(not hasattr(x, "foo"))
520 class C1(object):
521 __slots__ = ['a']
522 x = C1()
523 verify(not hasattr(x, "__dict__"))
524 verify(x.a == None)
525 x.a = 1
526 verify(x.a == 1)
527 del x.a
528 verify(x.a == None)
530 class C3(object):
531 __slots__ = ['a', 'b', 'c']
532 x = C3()
533 verify(not hasattr(x, "__dict__"))
534 verify(x.a is None)
535 verify(x.b is None)
536 verify(x.c is None)
537 x.a = 1
538 x.b = 2
539 x.c = 3
540 verify(x.a == 1)
541 verify(x.b == 2)
542 verify(x.c == 3)
544 def dynamics():
545 if verbose: print "Testing __dynamic__..."
546 verify(object.__dynamic__ == 0)
547 verify(list.__dynamic__ == 0)
548 class S1:
549 __metaclass__ = type
550 verify(S1.__dynamic__ == 0)
551 class S(object):
552 pass
553 verify(C.__dynamic__ == 0)
554 class D(object):
555 __dynamic__ = 1
556 verify(D.__dynamic__ == 1)
557 class E(D, S):
558 pass
559 verify(E.__dynamic__ == 1)
560 class F(S, D):
561 pass
562 verify(F.__dynamic__ == 1)
563 try:
564 S.foo = 1
565 except (AttributeError, TypeError):
566 pass
567 else:
568 verify(0, "assignment to a static class attribute should be illegal")
569 D.foo = 1
570 verify(D.foo == 1)
571 # Test that dynamic attributes are inherited
572 verify(E.foo == 1)
573 verify(F.foo == 1)
574 class SS(D):
575 __dynamic__ = 0
576 verify(SS.__dynamic__ == 0)
577 verify(SS.foo == 1)
578 try:
579 SS.foo = 1
580 except (AttributeError, TypeError):
581 pass
582 else:
583 verify(0, "assignment to SS.foo should be illegal")
585 def errors():
586 if verbose: print "Testing errors..."
588 try:
589 class C(list, dictionary):
590 pass
591 except TypeError:
592 pass
593 else:
594 verify(0, "inheritance from both list and dict should be illegal")
596 try:
597 class C(object, None):
598 pass
599 except TypeError:
600 pass
601 else:
602 verify(0, "inheritance from non-type should be illegal")
603 class Classic:
604 pass
606 try:
607 class C(object, Classic):
608 pass
609 except TypeError:
610 pass
611 else:
612 verify(0, "inheritance from object and Classic should be illegal")
614 try:
615 class C(int):
616 pass
617 except TypeError:
618 pass
619 else:
620 verify(0, "inheritance from int should be illegal")
622 try:
623 class C(object):
624 __slots__ = 1
625 except TypeError:
626 pass
627 else:
628 verify(0, "__slots__ = 1 should be illegal")
630 try:
631 class C(object):
632 __slots__ = [1]
633 except TypeError:
634 pass
635 else:
636 verify(0, "__slots__ = [1] should be illegal")
638 def classmethods():
639 if verbose: print "Testing class methods..."
640 class C(object):
641 def foo(*a): return a
642 goo = classmethod(foo)
643 c = C()
644 verify(C.goo(1) == (C, 1))
645 verify(c.goo(1) == (C, 1))
646 verify(c.foo(1) == (c, 1))
647 class D(C):
648 pass
649 d = D()
650 verify(D.goo(1) == (D, 1))
651 verify(d.goo(1) == (D, 1))
652 verify(d.foo(1) == (d, 1))
653 verify(D.foo(d, 1) == (d, 1))
655 def staticmethods():
656 if verbose: print "Testing static methods..."
657 class C(object):
658 def foo(*a): return a
659 goo = staticmethod(foo)
660 c = C()
661 verify(C.goo(1) == (1,))
662 verify(c.goo(1) == (1,))
663 verify(c.foo(1) == (c, 1,))
664 class D(C):
665 pass
666 d = D()
667 verify(D.goo(1) == (1,))
668 verify(d.goo(1) == (1,))
669 verify(d.foo(1) == (d, 1))
670 verify(D.foo(d, 1) == (d, 1))
672 def classic():
673 if verbose: print "Testing classic classes..."
674 class C:
675 def foo(*a): return a
676 goo = classmethod(foo)
677 c = C()
678 verify(C.goo(1) == (C, 1))
679 verify(c.goo(1) == (C, 1))
680 verify(c.foo(1) == (c, 1))
681 class D(C):
682 pass
683 d = D()
684 verify(D.goo(1) == (D, 1))
685 verify(d.goo(1) == (D, 1))
686 verify(d.foo(1) == (d, 1))
687 verify(D.foo(d, 1) == (d, 1))
689 def compattr():
690 if verbose: print "Testing computed attributes..."
691 class C(object):
692 class computed_attribute(object):
693 def __init__(self, get, set=None):
694 self.__get = get
695 self.__set = set
696 def __get__(self, obj, type=None):
697 return self.__get(obj)
698 def __set__(self, obj, value):
699 return self.__set(obj, value)
700 def __init__(self):
701 self.__x = 0
702 def __get_x(self):
703 x = self.__x
704 self.__x = x+1
705 return x
706 def __set_x(self, x):
707 self.__x = x
708 x = computed_attribute(__get_x, __set_x)
709 a = C()
710 verify(a.x == 0)
711 verify(a.x == 1)
712 a.x = 10
713 verify(a.x == 10)
714 verify(a.x == 11)
716 def newslot():
717 if verbose: print "Testing __new__ slot override..."
718 class C(list):
719 def __new__(cls):
720 self = list.__new__(cls)
721 self.foo = 1
722 return self
723 def __init__(self):
724 self.foo = self.foo + 2
725 a = C()
726 verify(a.foo == 3)
727 verify(a.__class__ is C)
728 class D(C):
729 pass
730 b = D()
731 verify(b.foo == 3)
732 verify(b.__class__ is D)
734 class PerverseMetaType(type):
735 def mro(cls):
736 L = type.mro(cls)
737 L.reverse()
738 return L
740 def altmro():
741 if verbose: print "Testing mro() and overriding it..."
742 class A(object):
743 def f(self): return "A"
744 class B(A):
745 pass
746 class C(A):
747 def f(self): return "C"
748 class D(B, C):
749 pass
750 verify(D.mro() == [D, B, C, A, object] == list(D.__mro__))
751 verify(D().f() == "C")
752 class X(A,B,C,D):
753 __metaclass__ = PerverseMetaType
754 verify(X.__mro__ == (object, A, C, B, D, X))
755 verify(X().f() == "A")
757 def overloading():
758 if verbose: print "testing operator overloading..."
760 class B(object):
761 "Intermediate class because object doesn't have a __setattr__"
763 class C(B):
765 def __getattr__(self, name):
766 if name == "foo":
767 return ("getattr", name)
768 else:
769 return B.__getattr__(self, name)
770 def __setattr__(self, name, value):
771 if name == "foo":
772 self.setattr = (name, value)
773 else:
774 return B.__setattr__(self, name, value)
775 def __delattr__(self, name):
776 if name == "foo":
777 self.delattr = name
778 else:
779 return B.__delattr__(self, name)
781 def __getitem__(self, key):
782 return ("getitem", key)
783 def __setitem__(self, key, value):
784 self.setitem = (key, value)
785 def __delitem__(self, key):
786 self.delitem = key
788 def __getslice__(self, i, j):
789 return ("getslice", i, j)
790 def __setslice__(self, i, j, value):
791 self.setslice = (i, j, value)
792 def __delslice__(self, i, j):
793 self.delslice = (i, j)
795 a = C()
796 verify(a.foo == ("getattr", "foo"))
797 a.foo = 12
798 verify(a.setattr == ("foo", 12))
799 del a.foo
800 verify(a.delattr == "foo")
802 verify(a[12] == ("getitem", 12))
803 a[12] = 21
804 verify(a.setitem == (12, 21))
805 del a[12]
806 verify(a.delitem == 12)
808 verify(a[0:10] == ("getslice", 0, 10))
809 a[0:10] = "foo"
810 verify(a.setslice == (0, 10, "foo"))
811 del a[0:10]
812 verify(a.delslice == (0, 10))
814 def all():
815 lists()
816 dicts()
817 ints()
818 longs()
819 floats()
820 complexes()
821 spamlists()
822 spamdicts()
823 pydicts()
824 pylists()
825 metaclass()
826 pymods()
827 multi()
828 diamond()
829 objects()
830 slots()
831 dynamics()
832 errors()
833 classmethods()
834 staticmethods()
835 classic()
836 compattr()
837 newslot()
838 altmro()
839 overloading()
841 all()
843 if verbose: print "All OK"