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