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
9 verify(eval(expr
, dict) == res
)
12 verify(m
== t
.__dict
__[meth
])
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
)
23 verify(m
== t
.__dict
__[meth
])
24 verify(m(a
, 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
)
34 verify(m
== t
.__dict
__[meth
])
35 verify(m(a
, b
, c
) == res
)
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
}
43 verify(dict['a'] == res
)
46 verify(m
== t
.__dict
__[meth
])
47 dict['a'] = deepcopy(a
)
49 verify(dict['a'] == res
)
50 dict['a'] = deepcopy(a
)
51 bm
= getattr(dict['a'], meth
)
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
}
59 verify(dict['a'] == res
)
62 verify(m
== t
.__dict
__[meth
])
63 dict['a'] = deepcopy(a
)
65 verify(dict['a'] == res
)
66 dict['a'] = deepcopy(a
)
67 bm
= getattr(dict['a'], meth
)
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
}
75 verify(dict['a'] == res
)
78 verify(m
== t
.__dict
__[meth
])
79 dict['a'] = deepcopy(a
)
81 verify(dict['a'] == res
)
82 dict['a'] = deepcopy(a
)
83 bm
= getattr(dict['a'], meth
)
85 verify(dict['a'] == res
)
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__")
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__")
110 for i
in d
.keys(): l1
.append(i
)
112 for i
in iter(d
): l
.append(i
)
115 for i
in d
.__iter
__(): l
.append(i
)
118 for i
in dictionary
.__iter
__(d
): l
.append(i
)
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__")
148 for name
, expr
in binops
.items():
150 expr
= expr
+ "(a, b)"
152 expr
= 'a %s b' % expr
167 for name
, expr
in unops
.items():
174 def numops(a
, b
, skip
=[]):
175 dict = {'a': a
, 'b': b
}
176 for name
, expr
in binops
.items():
178 name
= "__%s__" % name
180 res
= eval(expr
, dict)
181 testbinop(a
, b
, res
, expr
, name
)
182 for name
, expr
in unops
.items():
183 name
= "__%s__" % name
185 res
= eval(expr
, dict)
186 testunop(a
, res
, expr
, name
)
189 if verbose
: print "Testing int operations..."
193 if verbose
: print "Testing long operations..."
197 if verbose
: print "Testing float operations..."
201 if verbose
: print "Testing complex operations..."
202 numops(100.0j
, 3.0j
, skip
=['lt', 'le', 'gt', 'ge'])
203 class Number(complex):
205 def __init__(self
, *args
, **kwds
):
206 self
.prec
= kwds
.get('prec', 12)
210 return "%.*g" % (prec
, self
.real
)
212 return "%.*gj" % (prec
, self
.imag
)
213 return "(%.*g+%.*gj)" % (prec
, self
.real
, prec
, self
.imag
)
215 a
= Number(3.14, prec
=6)
216 verify(`a`
== "3.14")
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]),
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__")
244 class C(spam
.spamlist
):
245 def foo(self
): return 1
251 verify(a
.getstate() == 0)
253 verify(a
.getstate() == 42)
256 if verbose
: print "Testing spamdict operations..."
257 import copy
, xxsubtype
as spam
258 def spamdict(d
, memo
=None):
259 import xxsubtype
as spam
261 for k
, v
in d
.items(): sd
[k
] = v
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})
272 for i
in d
.keys(): l1
.append(i
)
274 for i
in iter(d
): l
.append(i
)
277 for i
in d
.__iter
__(): l
.append(i
)
280 for i
in type(spamdict({})).__iter
__(d
): l
.append(i
)
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__")
289 class C(spam
.spamdict
):
290 def foo(self
): return 1
292 verify(a
.items() == [])
295 verify(a
.items() == [('foo', 'bar')])
296 verify(a
.getstate() == 0)
298 verify(a
.getstate() == 100)
301 if verbose
: print "Testing Python subclass of dict..."
302 verify(issubclass(dictionary
, dictionary
))
303 verify(isinstance({}, dictionary
))
306 verify(d
.__class
__ is dictionary
)
307 verify(isinstance(d
, dictionary
))
310 def __init__(self
, *a
, **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
):
325 verify(issubclass(C
, dictionary
))
327 verify(a1
.state
== 12)
329 verify(a2
[1] == 'foo' and a2
[2] == 'bar')
331 verify(a
.state
== -1)
332 verify(a
.getstate() == -1)
335 verify(a
.getstate() == 0)
337 verify(a
.state
== 10)
338 verify(a
.getstate() == 10)
342 if verbose
: print "pydict stress test ..."
350 verify(a
[i
][j
] == i
*j
)
353 if verbose
: print "Testing Python subclass of list..."
355 def __getitem__(self
, i
):
356 return list.__getitem
__(self
, i
) + 100
357 def __getslice__(self
, i
, j
):
364 verify(a
[100:200] == (100,200))
367 if verbose
: print "Testing __metaclass__..."
375 def setstate(self
, state
):
378 verify(a
.getstate() == 0)
380 verify(a
.getstate() == 10)
382 class __metaclass__(type):
383 def myself(cls
): return cls
384 verify(D
.myself() == D
)
390 if verbose
: print "Testing Python subclass of module..."
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
)
409 verify(log
== [('getattr', '__init__'),
410 ('getattr', '__setattr__'),
411 ("setattr", "foo", 12),
413 ('getattr', '__delattr__'),
414 ("delattr", "foo")], log
)
417 if verbose
: print "Testing multiple inheritance..."
424 def setstate(self
, state
):
427 verify(a
.getstate() == 0)
429 verify(a
.getstate() == 10)
430 class D(dictionary
, C
):
432 type({}).__init
__(self
)
435 verify(d
.keys() == [])
437 verify(d
.items() == [("hello", "world")])
438 verify(d
["hello"] == "world")
439 verify(d
.getstate() == 0)
441 verify(d
.getstate() == 10)
442 verify(D
.__mro
__ == (D
, dictionary
, C
, object))
447 return int(self
.foo())
450 class Frag(Node
, list):
453 verify(Node().__int
__() == 23)
454 verify(int(Node()) == 23)
455 verify(Frag().__int
__() == 42)
456 verify(int(Frag()) == 42)
459 if verbose
: print "Testing multiple inheritance special cases..."
461 def spam(self
): return "A"
462 verify(A().spam() == "A")
464 def boo(self
): return "B"
465 def spam(self
): return "B"
466 verify(B().spam() == "B")
467 verify(B().boo() == "B")
469 def boo(self
): return "C"
470 verify(C().spam() == "A")
471 verify(C().boo() == "C")
473 verify(D().spam() == "B")
474 verify(D().boo() == "B")
475 verify(D
.__mro
__ == (D
, B
, C
, A
, object))
477 verify(E().spam() == "B")
478 verify(E().boo() == "C")
479 verify(E
.__mro
__ == (E
, C
, B
, A
, object))
481 verify(F().spam() == "B")
482 verify(F().boo() == "B")
483 verify(F
.__mro
__ == (F
, D
, E
, B
, C
, A
, object))
485 verify(G().spam() == "B")
486 verify(G().boo() == "C")
487 verify(G
.__mro
__ == (G
, E
, D
, C
, B
, A
, object))
490 if verbose
: print "Testing object class..."
492 verify(a
.__class
__ == object == type(a
))
495 verify(not hasattr(a
, "foo"))
498 except (AttributeError, TypeError):
501 verify(0, "object() should not allow setting a foo attribute")
502 verify(not hasattr(object(), "__dict__"))
507 verify(x
.__dict
__ is None)
510 verify(x
.__dict
__ == {'foo': 1})
513 if verbose
: print "Testing __slots__..."
517 verify(not hasattr(x
, "__dict__"))
518 verify(not hasattr(x
, "foo"))
523 verify(not hasattr(x
, "__dict__"))
531 __slots__
= ['a', 'b', 'c']
533 verify(not hasattr(x
, "__dict__"))
545 if verbose
: print "Testing __dynamic__..."
546 verify(object.__dynamic
__ == 0)
547 verify(list.__dynamic
__ == 0)
550 verify(S1
.__dynamic__
== 0)
553 verify(C
.__dynamic
__ == 0)
556 verify(D
.__dynamic
__ == 1)
559 verify(E
.__dynamic
__ == 1)
562 verify(F
.__dynamic
__ == 1)
565 except (AttributeError, TypeError):
568 verify(0, "assignment to a static class attribute should be illegal")
571 # Test that dynamic attributes are inherited
576 verify(SS
.__dynamic
__ == 0)
580 except (AttributeError, TypeError):
583 verify(0, "assignment to SS.foo should be illegal")
586 if verbose
: print "Testing errors..."
589 class C(list, dictionary
):
594 verify(0, "inheritance from both list and dict should be illegal")
597 class C(object, None):
602 verify(0, "inheritance from non-type should be illegal")
607 class C(object, Classic
):
612 verify(0, "inheritance from object and Classic should be illegal")
620 verify(0, "inheritance from int should be illegal")
628 verify(0, "__slots__ = 1 should be illegal")
636 verify(0, "__slots__ = [1] should be illegal")
639 if verbose
: print "Testing class methods..."
641 def foo(*a
): return a
642 goo
= classmethod(foo
)
644 verify(C
.goo(1) == (C
, 1))
645 verify(c
.goo(1) == (C
, 1))
646 verify(c
.foo(1) == (c
, 1))
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))
656 if verbose
: print "Testing static methods..."
658 def foo(*a
): return a
659 goo
= staticmethod(foo
)
661 verify(C
.goo(1) == (1,))
662 verify(c
.goo(1) == (1,))
663 verify(c
.foo(1) == (c
, 1,))
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))
673 if verbose
: print "Testing classic classes..."
675 def foo(*a
): return a
676 goo
= classmethod(foo
)
678 verify(C
.goo(1) == (C
, 1))
679 verify(c
.goo(1) == (C
, 1))
680 verify(c
.foo(1) == (c
, 1))
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))
690 if verbose
: print "Testing computed attributes..."
692 class computed_attribute(object):
693 def __init__(self
, get
, set=None):
696 def __get__(self
, obj
, type=None):
697 return self
.__get
(obj
)
698 def __set__(self
, obj
, value
):
699 return self
.__set
(obj
, value
)
706 def __set_x(self
, x
):
708 x
= computed_attribute(__get_x
, __set_x
)
717 if verbose
: print "Testing __new__ slot override..."
720 self
= list.__new
__(cls
)
724 self
.foo
= self
.foo
+ 2
727 verify(a
.__class
__ is C
)
732 verify(b
.__class
__ is D
)
734 class PerverseMetaType(type):
741 if verbose
: print "Testing mro() and overriding it..."
743 def f(self
): return "A"
747 def f(self
): return "C"
750 verify(D
.mro() == [D
, B
, C
, A
, object] == list(D
.__mro
__))
751 verify(D().f() == "C")
753 __metaclass__
= PerverseMetaType
754 verify(X
.__mro
__ == (object, A
, C
, B
, D
, X
))
755 verify(X().f() == "A")
758 if verbose
: print "testing operator overloading..."
761 "Intermediate class because object doesn't have a __setattr__"
765 def __getattr__(self
, name
):
767 return ("getattr", name
)
769 return B
.__getattr
__(self
, name
)
770 def __setattr__(self
, name
, value
):
772 self
.setattr = (name
, value
)
774 return B
.__setattr
__(self
, name
, value
)
775 def __delattr__(self
, name
):
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
):
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
)
796 verify(a
.foo
== ("getattr", "foo"))
798 verify(a
.setattr == ("foo", 12))
800 verify(a
.delattr == "foo")
802 verify(a
[12] == ("getitem", 12))
804 verify(a
.setitem
== (12, 21))
806 verify(a
.delitem
== 12)
808 verify(a
[0:10] == ("getslice", 0, 10))
810 verify(a
.setslice
== (0, 10, "foo"))
812 verify(a
.delslice
== (0, 10))
843 if verbose
: print "All OK"