/Lib/test/test_descr.py

http://unladen-swallow.googlecode.com/ · Python · 4425 lines · 3694 code · 431 blank · 300 comment · 481 complexity · 154a82e1036326d97a17bd58f1abf836 MD5 · raw file

Large files are truncated click here to view the full file

  1. import __builtin__
  2. import sys
  3. import types
  4. import unittest
  5. import warnings
  6. from copy import deepcopy
  7. from test import test_support
  8. class OperatorsTest(unittest.TestCase):
  9. def __init__(self, *args, **kwargs):
  10. unittest.TestCase.__init__(self, *args, **kwargs)
  11. self.binops = {
  12. 'add': '+',
  13. 'sub': '-',
  14. 'mul': '*',
  15. 'div': '/',
  16. 'divmod': 'divmod',
  17. 'pow': '**',
  18. 'lshift': '<<',
  19. 'rshift': '>>',
  20. 'and': '&',
  21. 'xor': '^',
  22. 'or': '|',
  23. 'cmp': 'cmp',
  24. 'lt': '<',
  25. 'le': '<=',
  26. 'eq': '==',
  27. 'ne': '!=',
  28. 'gt': '>',
  29. 'ge': '>=',
  30. }
  31. for name, expr in self.binops.items():
  32. if expr.islower():
  33. expr = expr + "(a, b)"
  34. else:
  35. expr = 'a %s b' % expr
  36. self.binops[name] = expr
  37. self.unops = {
  38. 'pos': '+',
  39. 'neg': '-',
  40. 'abs': 'abs',
  41. 'invert': '~',
  42. 'int': 'int',
  43. 'long': 'long',
  44. 'float': 'float',
  45. 'oct': 'oct',
  46. 'hex': 'hex',
  47. }
  48. for name, expr in self.unops.items():
  49. if expr.islower():
  50. expr = expr + "(a)"
  51. else:
  52. expr = '%s a' % expr
  53. self.unops[name] = expr
  54. def setUp(self):
  55. self.original_filters = warnings.filters[:]
  56. warnings.filterwarnings("ignore",
  57. r'complex divmod\(\), // and % are deprecated$',
  58. DeprecationWarning, r'(<string>|%s)$' % __name__)
  59. def tearDown(self):
  60. warnings.filters = self.original_filters
  61. def unop_test(self, a, res, expr="len(a)", meth="__len__"):
  62. d = {'a': a}
  63. self.assertEqual(eval(expr, d), res)
  64. t = type(a)
  65. m = getattr(t, meth)
  66. # Find method in parent class
  67. while meth not in t.__dict__:
  68. t = t.__bases__[0]
  69. self.assertEqual(m, t.__dict__[meth])
  70. self.assertEqual(m(a), res)
  71. bm = getattr(a, meth)
  72. self.assertEqual(bm(), res)
  73. def binop_test(self, a, b, res, expr="a+b", meth="__add__"):
  74. d = {'a': a, 'b': b}
  75. # XXX Hack so this passes before 2.3 when -Qnew is specified.
  76. if meth == "__div__" and 1/2 == 0.5:
  77. meth = "__truediv__"
  78. if meth == '__divmod__': pass
  79. self.assertEqual(eval(expr, d), res)
  80. t = type(a)
  81. m = getattr(t, meth)
  82. while meth not in t.__dict__:
  83. t = t.__bases__[0]
  84. self.assertEqual(m, t.__dict__[meth])
  85. self.assertEqual(m(a, b), res)
  86. bm = getattr(a, meth)
  87. self.assertEqual(bm(b), res)
  88. def ternop_test(self, a, b, c, res, expr="a[b:c]", meth="__getslice__"):
  89. d = {'a': a, 'b': b, 'c': c}
  90. self.assertEqual(eval(expr, d), res)
  91. t = type(a)
  92. m = getattr(t, meth)
  93. while meth not in t.__dict__:
  94. t = t.__bases__[0]
  95. self.assertEqual(m, t.__dict__[meth])
  96. self.assertEqual(m(a, b, c), res)
  97. bm = getattr(a, meth)
  98. self.assertEqual(bm(b, c), res)
  99. def setop_test(self, a, b, res, stmt="a+=b", meth="__iadd__"):
  100. d = {'a': deepcopy(a), 'b': b}
  101. exec stmt in d
  102. self.assertEqual(d['a'], res)
  103. t = type(a)
  104. m = getattr(t, meth)
  105. while meth not in t.__dict__:
  106. t = t.__bases__[0]
  107. self.assertEqual(m, t.__dict__[meth])
  108. d['a'] = deepcopy(a)
  109. m(d['a'], b)
  110. self.assertEqual(d['a'], res)
  111. d['a'] = deepcopy(a)
  112. bm = getattr(d['a'], meth)
  113. bm(b)
  114. self.assertEqual(d['a'], res)
  115. def set2op_test(self, a, b, c, res, stmt="a[b]=c", meth="__setitem__"):
  116. d = {'a': deepcopy(a), 'b': b, 'c': c}
  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, c)
  126. self.assertEqual(d['a'], res)
  127. d['a'] = deepcopy(a)
  128. bm = getattr(d['a'], meth)
  129. bm(b, c)
  130. self.assertEqual(d['a'], res)
  131. def set3op_test(self, a, b, c, d, res, stmt="a[b:c]=d", meth="__setslice__"):
  132. dictionary = {'a': deepcopy(a), 'b': b, 'c': c, 'd': d}
  133. exec stmt in dictionary
  134. self.assertEqual(dictionary['a'], res)
  135. t = type(a)
  136. while meth not in t.__dict__:
  137. t = t.__bases__[0]
  138. m = getattr(t, meth)
  139. self.assertEqual(m, t.__dict__[meth])
  140. dictionary['a'] = deepcopy(a)
  141. m(dictionary['a'], b, c, d)
  142. self.assertEqual(dictionary['a'], res)
  143. dictionary['a'] = deepcopy(a)
  144. bm = getattr(dictionary['a'], meth)
  145. bm(b, c, d)
  146. self.assertEqual(dictionary['a'], res)
  147. def test_lists(self):
  148. # Testing list operations...
  149. # Asserts are within individual test methods
  150. self.binop_test([1], [2], [1,2], "a+b", "__add__")
  151. self.binop_test([1,2,3], 2, 1, "b in a", "__contains__")
  152. self.binop_test([1,2,3], 4, 0, "b in a", "__contains__")
  153. self.binop_test([1,2,3], 1, 2, "a[b]", "__getitem__")
  154. self.ternop_test([1,2,3], 0, 2, [1,2], "a[b:c]", "__getslice__")
  155. self.setop_test([1], [2], [1,2], "a+=b", "__iadd__")
  156. self.setop_test([1,2], 3, [1,2,1,2,1,2], "a*=b", "__imul__")
  157. self.unop_test([1,2,3], 3, "len(a)", "__len__")
  158. self.binop_test([1,2], 3, [1,2,1,2,1,2], "a*b", "__mul__")
  159. self.binop_test([1,2], 3, [1,2,1,2,1,2], "b*a", "__rmul__")
  160. self.set2op_test([1,2], 1, 3, [1,3], "a[b]=c", "__setitem__")
  161. self.set3op_test([1,2,3,4], 1, 3, [5,6], [1,5,6,4], "a[b:c]=d",
  162. "__setslice__")
  163. def test_dicts(self):
  164. # Testing dict operations...
  165. self.binop_test({1:2}, {2:1}, -1, "cmp(a,b)", "__cmp__")
  166. self.binop_test({1:2,3:4}, 1, 1, "b in a", "__contains__")
  167. self.binop_test({1:2,3:4}, 2, 0, "b in a", "__contains__")
  168. self.binop_test({1:2,3:4}, 1, 2, "a[b]", "__getitem__")
  169. d = {1:2, 3:4}
  170. l1 = []
  171. for i in d.keys():
  172. l1.append(i)
  173. l = []
  174. for i in iter(d):
  175. l.append(i)
  176. self.assertEqual(l, l1)
  177. l = []
  178. for i in d.__iter__():
  179. l.append(i)
  180. self.assertEqual(l, l1)
  181. l = []
  182. for i in dict.__iter__(d):
  183. l.append(i)
  184. self.assertEqual(l, l1)
  185. d = {1:2, 3:4}
  186. self.unop_test(d, 2, "len(a)", "__len__")
  187. self.assertEqual(eval(repr(d), {}), d)
  188. self.assertEqual(eval(d.__repr__(), {}), d)
  189. self.set2op_test({1:2,3:4}, 2, 3, {1:2,2:3,3:4}, "a[b]=c",
  190. "__setitem__")
  191. # Tests for unary and binary operators
  192. def number_operators(self, a, b, skip=[]):
  193. dict = {'a': a, 'b': b}
  194. for name, expr in self.binops.items():
  195. if name not in skip:
  196. name = "__%s__" % name
  197. if hasattr(a, name):
  198. res = eval(expr, dict)
  199. self.binop_test(a, b, res, expr, name)
  200. for name, expr in self.unops.items():
  201. if name not in skip:
  202. name = "__%s__" % name
  203. if hasattr(a, name):
  204. res = eval(expr, dict)
  205. self.unop_test(a, res, expr, name)
  206. def test_ints(self):
  207. # Testing int operations...
  208. self.number_operators(100, 3)
  209. # The following crashes in Python 2.2
  210. self.assertEqual((1).__nonzero__(), 1)
  211. self.assertEqual((0).__nonzero__(), 0)
  212. # This returns 'NotImplemented' in Python 2.2
  213. class C(int):
  214. def __add__(self, other):
  215. return NotImplemented
  216. self.assertEqual(C(5L), 5)
  217. try:
  218. C() + ""
  219. except TypeError:
  220. pass
  221. else:
  222. self.fail("NotImplemented should have caused TypeError")
  223. import sys
  224. try:
  225. C(sys.maxint+1)
  226. except OverflowError:
  227. pass
  228. else:
  229. self.fail("should have raised OverflowError")
  230. def test_longs(self):
  231. # Testing long operations...
  232. self.number_operators(100L, 3L)
  233. def test_floats(self):
  234. # Testing float operations...
  235. self.number_operators(100.0, 3.0)
  236. def test_complexes(self):
  237. # Testing complex operations...
  238. self.number_operators(100.0j, 3.0j, skip=['lt', 'le', 'gt', 'ge',
  239. 'int', 'long', 'float'])
  240. class Number(complex):
  241. __slots__ = ['prec']
  242. def __new__(cls, *args, **kwds):
  243. result = complex.__new__(cls, *args)
  244. result.prec = kwds.get('prec', 12)
  245. return result
  246. def __repr__(self):
  247. prec = self.prec
  248. if self.imag == 0.0:
  249. return "%.*g" % (prec, self.real)
  250. if self.real == 0.0:
  251. return "%.*gj" % (prec, self.imag)
  252. return "(%.*g+%.*gj)" % (prec, self.real, prec, self.imag)
  253. __str__ = __repr__
  254. a = Number(3.14, prec=6)
  255. self.assertEqual(repr(a), "3.14")
  256. self.assertEqual(a.prec, 6)
  257. a = Number(a, prec=2)
  258. self.assertEqual(repr(a), "3.1")
  259. self.assertEqual(a.prec, 2)
  260. a = Number(234.5)
  261. self.assertEqual(repr(a), "234.5")
  262. self.assertEqual(a.prec, 12)
  263. def test_spam_lists(self):
  264. # Testing spamlist operations...
  265. import copy, xxsubtype as spam
  266. def spamlist(l, memo=None):
  267. import xxsubtype as spam
  268. return spam.spamlist(l)
  269. # This is an ugly hack:
  270. copy._deepcopy_dispatch[spam.spamlist] = spamlist
  271. self.binop_test(spamlist([1]), spamlist([2]), spamlist([1,2]), "a+b",
  272. "__add__")
  273. self.binop_test(spamlist([1,2,3]), 2, 1, "b in a", "__contains__")
  274. self.binop_test(spamlist([1,2,3]), 4, 0, "b in a", "__contains__")
  275. self.binop_test(spamlist([1,2,3]), 1, 2, "a[b]", "__getitem__")
  276. self.ternop_test(spamlist([1,2,3]), 0, 2, spamlist([1,2]), "a[b:c]",
  277. "__getslice__")
  278. self.setop_test(spamlist([1]), spamlist([2]), spamlist([1,2]), "a+=b",
  279. "__iadd__")
  280. self.setop_test(spamlist([1,2]), 3, spamlist([1,2,1,2,1,2]), "a*=b",
  281. "__imul__")
  282. self.unop_test(spamlist([1,2,3]), 3, "len(a)", "__len__")
  283. self.binop_test(spamlist([1,2]), 3, spamlist([1,2,1,2,1,2]), "a*b",
  284. "__mul__")
  285. self.binop_test(spamlist([1,2]), 3, spamlist([1,2,1,2,1,2]), "b*a",
  286. "__rmul__")
  287. self.set2op_test(spamlist([1,2]), 1, 3, spamlist([1,3]), "a[b]=c",
  288. "__setitem__")
  289. self.set3op_test(spamlist([1,2,3,4]), 1, 3, spamlist([5,6]),
  290. spamlist([1,5,6,4]), "a[b:c]=d", "__setslice__")
  291. # Test subclassing
  292. class C(spam.spamlist):
  293. def foo(self): return 1
  294. a = C()
  295. self.assertEqual(a, [])
  296. self.assertEqual(a.foo(), 1)
  297. a.append(100)
  298. self.assertEqual(a, [100])
  299. self.assertEqual(a.getstate(), 0)
  300. a.setstate(42)
  301. self.assertEqual(a.getstate(), 42)
  302. def test_spam_dicts(self):
  303. # Testing spamdict operations...
  304. import copy, xxsubtype as spam
  305. def spamdict(d, memo=None):
  306. import xxsubtype as spam
  307. sd = spam.spamdict()
  308. for k, v in d.items():
  309. sd[k] = v
  310. return sd
  311. # This is an ugly hack:
  312. copy._deepcopy_dispatch[spam.spamdict] = spamdict
  313. self.binop_test(spamdict({1:2}), spamdict({2:1}), -1, "cmp(a,b)",
  314. "__cmp__")
  315. self.binop_test(spamdict({1:2,3:4}), 1, 1, "b in a", "__contains__")
  316. self.binop_test(spamdict({1:2,3:4}), 2, 0, "b in a", "__contains__")
  317. self.binop_test(spamdict({1:2,3:4}), 1, 2, "a[b]", "__getitem__")
  318. d = spamdict({1:2,3:4})
  319. l1 = []
  320. for i in d.keys():
  321. l1.append(i)
  322. l = []
  323. for i in iter(d):
  324. l.append(i)
  325. self.assertEqual(l, l1)
  326. l = []
  327. for i in d.__iter__():
  328. l.append(i)
  329. self.assertEqual(l, l1)
  330. l = []
  331. for i in type(spamdict({})).__iter__(d):
  332. l.append(i)
  333. self.assertEqual(l, l1)
  334. straightd = {1:2, 3:4}
  335. spamd = spamdict(straightd)
  336. self.unop_test(spamd, 2, "len(a)", "__len__")
  337. self.unop_test(spamd, repr(straightd), "repr(a)", "__repr__")
  338. self.set2op_test(spamdict({1:2,3:4}), 2, 3, spamdict({1:2,2:3,3:4}),
  339. "a[b]=c", "__setitem__")
  340. # Test subclassing
  341. class C(spam.spamdict):
  342. def foo(self): return 1
  343. a = C()
  344. self.assertEqual(a.items(), [])
  345. self.assertEqual(a.foo(), 1)
  346. a['foo'] = 'bar'
  347. self.assertEqual(a.items(), [('foo', 'bar')])
  348. self.assertEqual(a.getstate(), 0)
  349. a.setstate(100)
  350. self.assertEqual(a.getstate(), 100)
  351. class ClassPropertiesAndMethods(unittest.TestCase):
  352. def test_python_dicts(self):
  353. # Testing Python subclass of dict...
  354. self.assert_(issubclass(dict, dict))
  355. self.assert_(isinstance({}, dict))
  356. d = dict()
  357. self.assertEqual(d, {})
  358. self.assert_(d.__class__ is dict)
  359. self.assert_(isinstance(d, dict))
  360. class C(dict):
  361. state = -1
  362. def __init__(self_local, *a, **kw):
  363. if a:
  364. self.assertEqual(len(a), 1)
  365. self_local.state = a[0]
  366. if kw:
  367. for k, v in kw.items():
  368. self_local[v] = k
  369. def __getitem__(self, key):
  370. return self.get(key, 0)
  371. def __setitem__(self_local, key, value):
  372. self.assert_(isinstance(key, type(0)))
  373. dict.__setitem__(self_local, key, value)
  374. def setstate(self, state):
  375. self.state = state
  376. def getstate(self):
  377. return self.state
  378. self.assert_(issubclass(C, dict))
  379. a1 = C(12)
  380. self.assertEqual(a1.state, 12)
  381. a2 = C(foo=1, bar=2)
  382. self.assertEqual(a2[1] == 'foo' and a2[2], 'bar')
  383. a = C()
  384. self.assertEqual(a.state, -1)
  385. self.assertEqual(a.getstate(), -1)
  386. a.setstate(0)
  387. self.assertEqual(a.state, 0)
  388. self.assertEqual(a.getstate(), 0)
  389. a.setstate(10)
  390. self.assertEqual(a.state, 10)
  391. self.assertEqual(a.getstate(), 10)
  392. self.assertEqual(a[42], 0)
  393. a[42] = 24
  394. self.assertEqual(a[42], 24)
  395. N = 50
  396. for i in range(N):
  397. a[i] = C()
  398. for j in range(N):
  399. a[i][j] = i*j
  400. for i in range(N):
  401. for j in range(N):
  402. self.assertEqual(a[i][j], i*j)
  403. def test_python_lists(self):
  404. # Testing Python subclass of list...
  405. class C(list):
  406. def __getitem__(self, i):
  407. return list.__getitem__(self, i) + 100
  408. def __getslice__(self, i, j):
  409. return (i, j)
  410. a = C()
  411. a.extend([0,1,2])
  412. self.assertEqual(a[0], 100)
  413. self.assertEqual(a[1], 101)
  414. self.assertEqual(a[2], 102)
  415. self.assertEqual(a[100:200], (100,200))
  416. def test_metaclass(self):
  417. # Testing __metaclass__...
  418. class C:
  419. __metaclass__ = type
  420. def __init__(self):
  421. self.__state = 0
  422. def getstate(self):
  423. return self.__state
  424. def setstate(self, state):
  425. self.__state = state
  426. a = C()
  427. self.assertEqual(a.getstate(), 0)
  428. a.setstate(10)
  429. self.assertEqual(a.getstate(), 10)
  430. class D:
  431. class __metaclass__(type):
  432. def myself(cls): return cls
  433. self.assertEqual(D.myself(), D)
  434. d = D()
  435. self.assertEqual(d.__class__, D)
  436. class M1(type):
  437. def __new__(cls, name, bases, dict):
  438. dict['__spam__'] = 1
  439. return type.__new__(cls, name, bases, dict)
  440. class C:
  441. __metaclass__ = M1
  442. self.assertEqual(C.__spam__, 1)
  443. c = C()
  444. self.assertEqual(c.__spam__, 1)
  445. class _instance(object):
  446. pass
  447. class M2(object):
  448. @staticmethod
  449. def __new__(cls, name, bases, dict):
  450. self = object.__new__(cls)
  451. self.name = name
  452. self.bases = bases
  453. self.dict = dict
  454. return self
  455. def __call__(self):
  456. it = _instance()
  457. # Early binding of methods
  458. for key in self.dict:
  459. if key.startswith("__"):
  460. continue
  461. setattr(it, key, self.dict[key].__get__(it, self))
  462. return it
  463. class C:
  464. __metaclass__ = M2
  465. def spam(self):
  466. return 42
  467. self.assertEqual(C.name, 'C')
  468. self.assertEqual(C.bases, ())
  469. self.assert_('spam' in C.dict)
  470. c = C()
  471. self.assertEqual(c.spam(), 42)
  472. # More metaclass examples
  473. class autosuper(type):
  474. # Automatically add __super to the class
  475. # This trick only works for dynamic classes
  476. def __new__(metaclass, name, bases, dict):
  477. cls = super(autosuper, metaclass).__new__(metaclass,
  478. name, bases, dict)
  479. # Name mangling for __super removes leading underscores
  480. while name[:1] == "_":
  481. name = name[1:]
  482. if name:
  483. name = "_%s__super" % name
  484. else:
  485. name = "__super"
  486. setattr(cls, name, super(cls))
  487. return cls
  488. class A:
  489. __metaclass__ = autosuper
  490. def meth(self):
  491. return "A"
  492. class B(A):
  493. def meth(self):
  494. return "B" + self.__super.meth()
  495. class C(A):
  496. def meth(self):
  497. return "C" + self.__super.meth()
  498. class D(C, B):
  499. def meth(self):
  500. return "D" + self.__super.meth()
  501. self.assertEqual(D().meth(), "DCBA")
  502. class E(B, C):
  503. def meth(self):
  504. return "E" + self.__super.meth()
  505. self.assertEqual(E().meth(), "EBCA")
  506. class autoproperty(type):
  507. # Automatically create property attributes when methods
  508. # named _get_x and/or _set_x are found
  509. def __new__(metaclass, name, bases, dict):
  510. hits = {}
  511. for key, val in dict.iteritems():
  512. if key.startswith("_get_"):
  513. key = key[5:]
  514. get, set = hits.get(key, (None, None))
  515. get = val
  516. hits[key] = get, set
  517. elif key.startswith("_set_"):
  518. key = key[5:]
  519. get, set = hits.get(key, (None, None))
  520. set = val
  521. hits[key] = get, set
  522. for key, (get, set) in hits.iteritems():
  523. dict[key] = property(get, set)
  524. return super(autoproperty, metaclass).__new__(metaclass,
  525. name, bases, dict)
  526. class A:
  527. __metaclass__ = autoproperty
  528. def _get_x(self):
  529. return -self.__x
  530. def _set_x(self, x):
  531. self.__x = -x
  532. a = A()
  533. self.assert_(not hasattr(a, "x"))
  534. a.x = 12
  535. self.assertEqual(a.x, 12)
  536. self.assertEqual(a._A__x, -12)
  537. class multimetaclass(autoproperty, autosuper):
  538. # Merge of multiple cooperating metaclasses
  539. pass
  540. class A:
  541. __metaclass__ = multimetaclass
  542. def _get_x(self):
  543. return "A"
  544. class B(A):
  545. def _get_x(self):
  546. return "B" + self.__super._get_x()
  547. class C(A):
  548. def _get_x(self):
  549. return "C" + self.__super._get_x()
  550. class D(C, B):
  551. def _get_x(self):
  552. return "D" + self.__super._get_x()
  553. self.assertEqual(D().x, "DCBA")
  554. # Make sure type(x) doesn't call x.__class__.__init__
  555. class T(type):
  556. counter = 0
  557. def __init__(self, *args):
  558. T.counter += 1
  559. class C:
  560. __metaclass__ = T
  561. self.assertEqual(T.counter, 1)
  562. a = C()
  563. self.assertEqual(type(a), C)
  564. self.assertEqual(T.counter, 1)
  565. class C(object): pass
  566. c = C()
  567. try: c()
  568. except TypeError: pass
  569. else: self.fail("calling object w/o call method should raise "
  570. "TypeError")
  571. # Testing code to find most derived baseclass
  572. class A(type):
  573. def __new__(*args, **kwargs):
  574. return type.__new__(*args, **kwargs)
  575. class B(object):
  576. pass
  577. class C(object):
  578. __metaclass__ = A
  579. # The most derived metaclass of D is A rather than type.
  580. class D(B, C):
  581. pass
  582. def test_module_subclasses(self):
  583. # Testing Python subclass of module...
  584. log = []
  585. import types, sys
  586. MT = type(sys)
  587. class MM(MT):
  588. def __init__(self, name):
  589. MT.__init__(self, name)
  590. def __getattribute__(self, name):
  591. log.append(("getattr", name))
  592. return MT.__getattribute__(self, name)
  593. def __setattr__(self, name, value):
  594. log.append(("setattr", name, value))
  595. MT.__setattr__(self, name, value)
  596. def __delattr__(self, name):
  597. log.append(("delattr", name))
  598. MT.__delattr__(self, name)
  599. a = MM("a")
  600. a.foo = 12
  601. x = a.foo
  602. del a.foo
  603. self.assertEqual(log, [("setattr", "foo", 12),
  604. ("getattr", "foo"),
  605. ("delattr", "foo")])
  606. # http://python.org/sf/1174712
  607. try:
  608. class Module(types.ModuleType, str):
  609. pass
  610. except TypeError:
  611. pass
  612. else:
  613. self.fail("inheriting from ModuleType and str at the same time "
  614. "should fail")
  615. def test_multiple_inheritence(self):
  616. # Testing multiple inheritance...
  617. class C(object):
  618. def __init__(self):
  619. self.__state = 0
  620. def getstate(self):
  621. return self.__state
  622. def setstate(self, state):
  623. self.__state = state
  624. a = C()
  625. self.assertEqual(a.getstate(), 0)
  626. a.setstate(10)
  627. self.assertEqual(a.getstate(), 10)
  628. class D(dict, C):
  629. def __init__(self):
  630. type({}).__init__(self)
  631. C.__init__(self)
  632. d = D()
  633. self.assertEqual(d.keys(), [])
  634. d["hello"] = "world"
  635. self.assertEqual(d.items(), [("hello", "world")])
  636. self.assertEqual(d["hello"], "world")
  637. self.assertEqual(d.getstate(), 0)
  638. d.setstate(10)
  639. self.assertEqual(d.getstate(), 10)
  640. self.assertEqual(D.__mro__, (D, dict, C, object))
  641. # SF bug #442833
  642. class Node(object):
  643. def __int__(self):
  644. return int(self.foo())
  645. def foo(self):
  646. return "23"
  647. class Frag(Node, list):
  648. def foo(self):
  649. return "42"
  650. self.assertEqual(Node().__int__(), 23)
  651. self.assertEqual(int(Node()), 23)
  652. self.assertEqual(Frag().__int__(), 42)
  653. self.assertEqual(int(Frag()), 42)
  654. # MI mixing classic and new-style classes.
  655. class A:
  656. x = 1
  657. class B(A):
  658. pass
  659. class C(A):
  660. x = 2
  661. class D(B, C):
  662. pass
  663. self.assertEqual(D.x, 1)
  664. # Classic MRO is preserved for a classic base class.
  665. class E(D, object):
  666. pass
  667. self.assertEqual(E.__mro__, (E, D, B, A, C, object))
  668. self.assertEqual(E.x, 1)
  669. # But with a mix of classic bases, their MROs are combined using
  670. # new-style MRO.
  671. class F(B, C, object):
  672. pass
  673. self.assertEqual(F.__mro__, (F, B, C, A, object))
  674. self.assertEqual(F.x, 2)
  675. # Try something else.
  676. class C:
  677. def cmethod(self):
  678. return "C a"
  679. def all_method(self):
  680. return "C b"
  681. class M1(C, object):
  682. def m1method(self):
  683. return "M1 a"
  684. def all_method(self):
  685. return "M1 b"
  686. self.assertEqual(M1.__mro__, (M1, C, object))
  687. m = M1()
  688. self.assertEqual(m.cmethod(), "C a")
  689. self.assertEqual(m.m1method(), "M1 a")
  690. self.assertEqual(m.all_method(), "M1 b")
  691. class D(C):
  692. def dmethod(self):
  693. return "D a"
  694. def all_method(self):
  695. return "D b"
  696. class M2(D, object):
  697. def m2method(self):
  698. return "M2 a"
  699. def all_method(self):
  700. return "M2 b"
  701. self.assertEqual(M2.__mro__, (M2, D, C, object))
  702. m = M2()
  703. self.assertEqual(m.cmethod(), "C a")
  704. self.assertEqual(m.dmethod(), "D a")
  705. self.assertEqual(m.m2method(), "M2 a")
  706. self.assertEqual(m.all_method(), "M2 b")
  707. class M3(M1, M2, object):
  708. def m3method(self):
  709. return "M3 a"
  710. def all_method(self):
  711. return "M3 b"
  712. self.assertEqual(M3.__mro__, (M3, M1, M2, D, C, object))
  713. m = M3()
  714. self.assertEqual(m.cmethod(), "C a")
  715. self.assertEqual(m.dmethod(), "D a")
  716. self.assertEqual(m.m1method(), "M1 a")
  717. self.assertEqual(m.m2method(), "M2 a")
  718. self.assertEqual(m.m3method(), "M3 a")
  719. self.assertEqual(m.all_method(), "M3 b")
  720. class Classic:
  721. pass
  722. try:
  723. class New(Classic):
  724. __metaclass__ = type
  725. except TypeError:
  726. pass
  727. else:
  728. self.fail("new class with only classic bases - shouldn't be")
  729. def test_diamond_inheritence(self):
  730. # Testing multiple inheritance special cases...
  731. class A(object):
  732. def spam(self): return "A"
  733. self.assertEqual(A().spam(), "A")
  734. class B(A):
  735. def boo(self): return "B"
  736. def spam(self): return "B"
  737. self.assertEqual(B().spam(), "B")
  738. self.assertEqual(B().boo(), "B")
  739. class C(A):
  740. def boo(self): return "C"
  741. self.assertEqual(C().spam(), "A")
  742. self.assertEqual(C().boo(), "C")
  743. class D(B, C): pass
  744. self.assertEqual(D().spam(), "B")
  745. self.assertEqual(D().boo(), "B")
  746. self.assertEqual(D.__mro__, (D, B, C, A, object))
  747. class E(C, B): pass
  748. self.assertEqual(E().spam(), "B")
  749. self.assertEqual(E().boo(), "C")
  750. self.assertEqual(E.__mro__, (E, C, B, A, object))
  751. # MRO order disagreement
  752. try:
  753. class F(D, E): pass
  754. except TypeError:
  755. pass
  756. else:
  757. self.fail("expected MRO order disagreement (F)")
  758. try:
  759. class G(E, D): pass
  760. except TypeError:
  761. pass
  762. else:
  763. self.fail("expected MRO order disagreement (G)")
  764. # see thread python-dev/2002-October/029035.html
  765. def test_ex5_from_c3_switch(self):
  766. # Testing ex5 from C3 switch discussion...
  767. class A(object): pass
  768. class B(object): pass
  769. class C(object): pass
  770. class X(A): pass
  771. class Y(A): pass
  772. class Z(X,B,Y,C): pass
  773. self.assertEqual(Z.__mro__, (Z, X, B, Y, A, C, object))
  774. # see "A Monotonic Superclass Linearization for Dylan",
  775. # by Kim Barrett et al. (OOPSLA 1996)
  776. def test_monotonicity(self):
  777. # Testing MRO monotonicity...
  778. class Boat(object): pass
  779. class DayBoat(Boat): pass
  780. class WheelBoat(Boat): pass
  781. class EngineLess(DayBoat): pass
  782. class SmallMultihull(DayBoat): pass
  783. class PedalWheelBoat(EngineLess,WheelBoat): pass
  784. class SmallCatamaran(SmallMultihull): pass
  785. class Pedalo(PedalWheelBoat,SmallCatamaran): pass
  786. self.assertEqual(PedalWheelBoat.__mro__,
  787. (PedalWheelBoat, EngineLess, DayBoat, WheelBoat, Boat, object))
  788. self.assertEqual(SmallCatamaran.__mro__,
  789. (SmallCatamaran, SmallMultihull, DayBoat, Boat, object))
  790. self.assertEqual(Pedalo.__mro__,
  791. (Pedalo, PedalWheelBoat, EngineLess, SmallCatamaran,
  792. SmallMultihull, DayBoat, WheelBoat, Boat, object))
  793. # see "A Monotonic Superclass Linearization for Dylan",
  794. # by Kim Barrett et al. (OOPSLA 1996)
  795. def test_consistency_with_epg(self):
  796. # Testing consistentcy with EPG...
  797. class Pane(object): pass
  798. class ScrollingMixin(object): pass
  799. class EditingMixin(object): pass
  800. class ScrollablePane(Pane,ScrollingMixin): pass
  801. class EditablePane(Pane,EditingMixin): pass
  802. class EditableScrollablePane(ScrollablePane,EditablePane): pass
  803. self.assertEqual(EditableScrollablePane.__mro__,
  804. (EditableScrollablePane, ScrollablePane, EditablePane, Pane,
  805. ScrollingMixin, EditingMixin, object))
  806. def test_mro_disagreement(self):
  807. # Testing error messages for MRO disagreement...
  808. mro_err_msg = """Cannot create a consistent method resolution
  809. order (MRO) for bases """
  810. def raises(exc, expected, callable, *args):
  811. try:
  812. callable(*args)
  813. except exc, msg:
  814. if not str(msg).startswith(expected):
  815. self.fail("Message %r, expected %r" % (str(msg), expected))
  816. else:
  817. self.fail("Expected %s" % exc)
  818. class A(object): pass
  819. class B(A): pass
  820. class C(object): pass
  821. # Test some very simple errors
  822. raises(TypeError, "duplicate base class A",
  823. type, "X", (A, A), {})
  824. raises(TypeError, mro_err_msg,
  825. type, "X", (A, B), {})
  826. raises(TypeError, mro_err_msg,
  827. type, "X", (A, C, B), {})
  828. # Test a slightly more complex error
  829. class GridLayout(object): pass
  830. class HorizontalGrid(GridLayout): pass
  831. class VerticalGrid(GridLayout): pass
  832. class HVGrid(HorizontalGrid, VerticalGrid): pass
  833. class VHGrid(VerticalGrid, HorizontalGrid): pass
  834. raises(TypeError, mro_err_msg,
  835. type, "ConfusedGrid", (HVGrid, VHGrid), {})
  836. def test_object_class(self):
  837. # Testing object class...
  838. a = object()
  839. self.assertEqual(a.__class__, object)
  840. self.assertEqual(type(a), object)
  841. b = object()
  842. self.assertNotEqual(a, b)
  843. self.assertFalse(hasattr(a, "foo"))
  844. try:
  845. a.foo = 12
  846. except (AttributeError, TypeError):
  847. pass
  848. else:
  849. self.fail("object() should not allow setting a foo attribute")
  850. self.assertFalse(hasattr(object(), "__dict__"))
  851. class Cdict(object):
  852. pass
  853. x = Cdict()
  854. self.assertEqual(x.__dict__, {})
  855. x.foo = 1
  856. self.assertEqual(x.foo, 1)
  857. self.assertEqual(x.__dict__, {'foo': 1})
  858. def test_slots(self):
  859. # Testing __slots__...
  860. class C0(object):
  861. __slots__ = []
  862. x = C0()
  863. self.assertFalse(hasattr(x, "__dict__"))
  864. self.assertFalse(hasattr(x, "foo"))
  865. class C1(object):
  866. __slots__ = ['a']
  867. x = C1()
  868. self.assertFalse(hasattr(x, "__dict__"))
  869. self.assertFalse(hasattr(x, "a"))
  870. x.a = 1
  871. self.assertEqual(x.a, 1)
  872. x.a = None
  873. self.assertEqual(x.a, None)
  874. del x.a
  875. self.assertFalse(hasattr(x, "a"))
  876. class C3(object):
  877. __slots__ = ['a', 'b', 'c']
  878. x = C3()
  879. self.assertFalse(hasattr(x, "__dict__"))
  880. self.assertFalse(hasattr(x, 'a'))
  881. self.assertFalse(hasattr(x, 'b'))
  882. self.assertFalse(hasattr(x, 'c'))
  883. x.a = 1
  884. x.b = 2
  885. x.c = 3
  886. self.assertEqual(x.a, 1)
  887. self.assertEqual(x.b, 2)
  888. self.assertEqual(x.c, 3)
  889. class C4(object):
  890. """Validate name mangling"""
  891. __slots__ = ['__a']
  892. def __init__(self, value):
  893. self.__a = value
  894. def get(self):
  895. return self.__a
  896. x = C4(5)
  897. self.assertFalse(hasattr(x, '__dict__'))
  898. self.assertFalse(hasattr(x, '__a'))
  899. self.assertEqual(x.get(), 5)
  900. try:
  901. x.__a = 6
  902. except AttributeError:
  903. pass
  904. else:
  905. self.fail("Double underscored names not mangled")
  906. # Make sure slot names are proper identifiers
  907. try:
  908. class C(object):
  909. __slots__ = [None]
  910. except TypeError:
  911. pass
  912. else:
  913. self.fail("[None] slots not caught")
  914. try:
  915. class C(object):
  916. __slots__ = ["foo bar"]
  917. except TypeError:
  918. pass
  919. else:
  920. self.fail("['foo bar'] slots not caught")
  921. try:
  922. class C(object):
  923. __slots__ = ["foo\0bar"]
  924. except TypeError:
  925. pass
  926. else:
  927. self.fail("['foo\\0bar'] slots not caught")
  928. try:
  929. class C(object):
  930. __slots__ = ["1"]
  931. except TypeError:
  932. pass
  933. else:
  934. self.fail("['1'] slots not caught")
  935. try:
  936. class C(object):
  937. __slots__ = [""]
  938. except TypeError:
  939. pass
  940. else:
  941. self.fail("[''] slots not caught")
  942. class C(object):
  943. __slots__ = ["a", "a_b", "_a", "A0123456789Z"]
  944. # XXX(nnorwitz): was there supposed to be something tested
  945. # from the class above?
  946. # Test a single string is not expanded as a sequence.
  947. class C(object):
  948. __slots__ = "abc"
  949. c = C()
  950. c.abc = 5
  951. self.assertEqual(c.abc, 5)
  952. # Test unicode slot names
  953. try:
  954. unicode
  955. except NameError:
  956. pass
  957. else:
  958. # Test a single unicode string is not expanded as a sequence.
  959. class C(object):
  960. __slots__ = unicode("abc")
  961. c = C()
  962. c.abc = 5
  963. self.assertEqual(c.abc, 5)
  964. # _unicode_to_string used to modify slots in certain circumstances
  965. slots = (unicode("foo"), unicode("bar"))
  966. class C(object):
  967. __slots__ = slots
  968. x = C()
  969. x.foo = 5
  970. self.assertEqual(x.foo, 5)
  971. self.assertEqual(type(slots[0]), unicode)
  972. # this used to leak references
  973. try:
  974. class C(object):
  975. __slots__ = [unichr(128)]
  976. except (TypeError, UnicodeEncodeError):
  977. pass
  978. else:
  979. self.fail("[unichr(128)] slots not caught")
  980. # Test leaks
  981. class Counted(object):
  982. counter = 0 # counts the number of instances alive
  983. def __init__(self):
  984. Counted.counter += 1
  985. def __del__(self):
  986. Counted.counter -= 1
  987. class C(object):
  988. __slots__ = ['a', 'b', 'c']
  989. x = C()
  990. x.a = Counted()
  991. x.b = Counted()
  992. x.c = Counted()
  993. self.assertEqual(Counted.counter, 3)
  994. del x
  995. self.assertEqual(Counted.counter, 0)
  996. class D(C):
  997. pass
  998. x = D()
  999. x.a = Counted()
  1000. x.z = Counted()
  1001. self.assertEqual(Counted.counter, 2)
  1002. del x
  1003. self.assertEqual(Counted.counter, 0)
  1004. class E(D):
  1005. __slots__ = ['e']
  1006. x = E()
  1007. x.a = Counted()
  1008. x.z = Counted()
  1009. x.e = Counted()
  1010. self.assertEqual(Counted.counter, 3)
  1011. del x
  1012. self.assertEqual(Counted.counter, 0)
  1013. # Test cyclical leaks [SF bug 519621]
  1014. class F(object):
  1015. __slots__ = ['a', 'b']
  1016. log = []
  1017. s = F()
  1018. s.a = [Counted(), s]
  1019. self.assertEqual(Counted.counter, 1)
  1020. s = None
  1021. import gc
  1022. gc.collect()
  1023. self.assertEqual(Counted.counter, 0)
  1024. # Test lookup leaks [SF bug 572567]
  1025. import sys,gc
  1026. class G(object):
  1027. def __cmp__(self, other):
  1028. return 0
  1029. __hash__ = None # Silence Py3k warning
  1030. g = G()
  1031. orig_objects = len(gc.get_objects())
  1032. for i in xrange(10):
  1033. g==g
  1034. new_objects = len(gc.get_objects())
  1035. self.assertEqual(orig_objects, new_objects)
  1036. class H(object):
  1037. __slots__ = ['a', 'b']
  1038. def __init__(self):
  1039. self.a = 1
  1040. self.b = 2
  1041. def __del__(self_):
  1042. self.assertEqual(self_.a, 1)
  1043. self.assertEqual(self_.b, 2)
  1044. with test_support.captured_output('stderr') as s:
  1045. h = H()
  1046. del h
  1047. self.assertEqual(s.getvalue(), '')
  1048. def test_slots_special(self):
  1049. # Testing __dict__ and __weakref__ in __slots__...
  1050. class D(object):
  1051. __slots__ = ["__dict__"]
  1052. a = D()
  1053. self.assert_(hasattr(a, "__dict__"))
  1054. self.assertFalse(hasattr(a, "__weakref__"))
  1055. a.foo = 42
  1056. self.assertEqual(a.__dict__, {"foo": 42})
  1057. class W(object):
  1058. __slots__ = ["__weakref__"]
  1059. a = W()
  1060. self.assert_(hasattr(a, "__weakref__"))
  1061. self.assertFalse(hasattr(a, "__dict__"))
  1062. try:
  1063. a.foo = 42
  1064. except AttributeError:
  1065. pass
  1066. else:
  1067. self.fail("shouldn't be allowed to set a.foo")
  1068. class C1(W, D):
  1069. __slots__ = []
  1070. a = C1()
  1071. self.assert_(hasattr(a, "__dict__"))
  1072. self.assert_(hasattr(a, "__weakref__"))
  1073. a.foo = 42
  1074. self.assertEqual(a.__dict__, {"foo": 42})
  1075. class C2(D, W):
  1076. __slots__ = []
  1077. a = C2()
  1078. self.assert_(hasattr(a, "__dict__"))
  1079. self.assert_(hasattr(a, "__weakref__"))
  1080. a.foo = 42
  1081. self.assertEqual(a.__dict__, {"foo": 42})
  1082. def test_slots_descriptor(self):
  1083. # Issue2115: slot descriptors did not correctly check
  1084. # the type of the given object
  1085. import abc
  1086. class MyABC:
  1087. __metaclass__ = abc.ABCMeta
  1088. __slots__ = "a"
  1089. class Unrelated(object):
  1090. pass
  1091. MyABC.register(Unrelated)
  1092. u = Unrelated()
  1093. self.assert_(isinstance(u, MyABC))
  1094. # This used to crash
  1095. self.assertRaises(TypeError, MyABC.a.__set__, u, 3)
  1096. def test_dynamics(self):
  1097. # Testing class attribute propagation...
  1098. class D(object):
  1099. pass
  1100. class E(D):
  1101. pass
  1102. class F(D):
  1103. pass
  1104. D.foo = 1
  1105. self.assertEqual(D.foo, 1)
  1106. # Test that dynamic attributes are inherited
  1107. self.assertEqual(E.foo, 1)
  1108. self.assertEqual(F.foo, 1)
  1109. # Test dynamic instances
  1110. class C(object):
  1111. pass
  1112. a = C()
  1113. self.assertFalse(hasattr(a, "foobar"))
  1114. C.foobar = 2
  1115. self.assertEqual(a.foobar, 2)
  1116. C.method = lambda self: 42
  1117. self.assertEqual(a.method(), 42)
  1118. C.__repr__ = lambda self: "C()"
  1119. self.assertEqual(repr(a), "C()")
  1120. C.__int__ = lambda self: 100
  1121. self.assertEqual(int(a), 100)
  1122. self.assertEqual(a.foobar, 2)
  1123. self.assertFalse(hasattr(a, "spam"))
  1124. def mygetattr(self, name):
  1125. if name == "spam":
  1126. return "spam"
  1127. raise AttributeError
  1128. C.__getattr__ = mygetattr
  1129. self.assertEqual(a.spam, "spam")
  1130. a.new = 12
  1131. self.assertEqual(a.new, 12)
  1132. def mysetattr(self, name, value):
  1133. if name == "spam":
  1134. raise AttributeError
  1135. return object.__setattr__(self, name, value)
  1136. C.__setattr__ = mysetattr
  1137. try:
  1138. a.spam = "not spam"
  1139. except AttributeError:
  1140. pass
  1141. else:
  1142. self.fail("expected AttributeError")
  1143. self.assertEqual(a.spam, "spam")
  1144. class D(C):
  1145. pass
  1146. d = D()
  1147. d.foo = 1
  1148. self.assertEqual(d.foo, 1)
  1149. # Test handling of int*seq and seq*int
  1150. class I(int):
  1151. pass
  1152. self.assertEqual("a"*I(2), "aa")
  1153. self.assertEqual(I(2)*"a", "aa")
  1154. self.assertEqual(2*I(3), 6)
  1155. self.assertEqual(I(3)*2, 6)
  1156. self.assertEqual(I(3)*I(2), 6)
  1157. # Test handling of long*seq and seq*long
  1158. class L(long):
  1159. pass
  1160. self.assertEqual("a"*L(2L), "aa")
  1161. self.assertEqual(L(2L)*"a", "aa")
  1162. self.assertEqual(2*L(3), 6)
  1163. self.assertEqual(L(3)*2, 6)
  1164. self.assertEqual(L(3)*L(2), 6)
  1165. # Test comparison of classes with dynamic metaclasses
  1166. class dynamicmetaclass(type):
  1167. pass
  1168. class someclass:
  1169. __metaclass__ = dynamicmetaclass
  1170. self.assertNotEqual(someclass, object)
  1171. def test_errors(self):
  1172. # Testing errors...
  1173. try:
  1174. class C(list, dict):
  1175. pass
  1176. except TypeError:
  1177. pass
  1178. else:
  1179. self.fail("inheritance from both list and dict should be illegal")
  1180. try:
  1181. class C(object, None):
  1182. pass
  1183. except TypeError:
  1184. pass
  1185. else:
  1186. self.fail("inheritance from non-type should be illegal")
  1187. class Classic:
  1188. pass
  1189. try:
  1190. class C(type(len)):
  1191. pass
  1192. except TypeError:
  1193. pass
  1194. else:
  1195. self.fail("inheritance from CFunction should be illegal")
  1196. try:
  1197. class C(object):
  1198. __slots__ = 1
  1199. except TypeError:
  1200. pass
  1201. else:
  1202. self.fail("__slots__ = 1 should be illegal")
  1203. try:
  1204. class C(object):
  1205. __slots__ = [1]
  1206. except TypeError:
  1207. pass
  1208. else:
  1209. self.fail("__slots__ = [1] should be illegal")
  1210. class M1(type):
  1211. pass
  1212. class M2(type):
  1213. pass
  1214. class A1(object):
  1215. __metaclass__ = M1
  1216. class A2(object):
  1217. __metaclass__ = M2
  1218. try:
  1219. class B(A1, A2):
  1220. pass
  1221. except TypeError:
  1222. pass
  1223. else:
  1224. self.fail("finding the most derived metaclass should have failed")
  1225. def test_classmethods(self):
  1226. # Testing class methods...
  1227. class C(object):
  1228. def foo(*a): return a
  1229. goo = classmethod(foo)
  1230. c = C()
  1231. self.assertEqual(C.goo(1), (C, 1))
  1232. self.assertEqual(c.goo(1), (C, 1))
  1233. self.assertEqual(c.foo(1), (c, 1))
  1234. class D(C):
  1235. pass
  1236. d = D()
  1237. self.assertEqual(D.goo(1), (D, 1))
  1238. self.assertEqual(d.goo(1), (D, 1))
  1239. self.assertEqual(d.foo(1), (d, 1))
  1240. self.assertEqual(D.foo(d, 1), (d, 1))
  1241. # Test for a specific crash (SF bug 528132)
  1242. def f(cls, arg): return (cls, arg)
  1243. ff = classmethod(f)
  1244. self.assertEqual(ff.__get__(0, int)(42), (int, 42))
  1245. self.assertEqual(ff.__get__(0)(42), (int, 42))
  1246. # Test super() with classmethods (SF bug 535444)
  1247. self.assertEqual(C.goo.im_self, C)
  1248. self.assertEqual(D.goo.im_self, D)
  1249. self.assertEqual(super(D,D).goo.im_self, D)
  1250. self.assertEqual(super(D,d).goo.im_self, D)
  1251. self.assertEqual(super(D,D).goo(), (D,))
  1252. self.assertEqual(super(D,d).goo(), (D,))
  1253. # Verify that argument is checked for callability (SF bug 753451)
  1254. try:
  1255. classmethod(1).__get__(1)
  1256. except TypeError:
  1257. pass
  1258. else:
  1259. self.fail("classmethod should check for callability")
  1260. # Verify that classmethod() doesn't allow keyword args
  1261. try:
  1262. classmethod(f, kw=1)
  1263. except TypeError:
  1264. pass
  1265. else:
  1266. self.fail("classmethod shouldn't accept keyword args")
  1267. def test_classmethods_in_c(self):
  1268. # Testing C-based class methods...
  1269. import xxsubtype as spam
  1270. a = (1, 2, 3)
  1271. d = {'abc': 123}
  1272. x, a1, d1 = spam.spamlist.classmeth(*a, **d)
  1273. self.assertEqual(x, spam.spamlist)
  1274. self.assertEqual(a, a1)
  1275. self.assertEqual(d, d1)
  1276. x, a1, d1 = spam.spamlist().classmeth(*a, **d)
  1277. self.assertEqual(x, spam.spamlist)
  1278. self.assertEqual(a, a1)
  1279. self.assertEqual(d, d1)
  1280. def test_staticmethods(self):
  1281. # Testing static methods...
  1282. class C(object):
  1283. def foo(*a): return a
  1284. goo = staticmethod(foo)
  1285. c = C()
  1286. self.assertEqual(C.goo(1), (1,))
  1287. self.assertEqual(c.goo(1), (1,))
  1288. self.assertEqual(c.foo(1), (c, 1,))
  1289. class D(C):
  1290. pass
  1291. d = D()
  1292. self.assertEqual(D.goo(1), (1,))
  1293. self.assertEqual(d.goo(1), (1,))
  1294. self.assertEqual(d.foo(1), (d, 1))
  1295. self.assertEqual(D.foo(d, 1), (d, 1))
  1296. def test_staticmethods_in_c(self):
  1297. # Testing C-based static methods...
  1298. import xxsubtype as spam
  1299. a = (1, 2, 3)
  1300. d = {"abc": 123}
  1301. x, a1, d1 = spam.spamlist.staticmeth(*a, **d)
  1302. self.assertEqual(x, None)
  1303. self.assertEqual(a, a1)
  1304. self.assertEqual(d, d1)
  1305. x, a1, d2 = spam.spamlist().staticmeth(*a, **d)
  1306. self.assertEqual(x, None)
  1307. self.assertEqual(a, a1)
  1308. self.assertEqual(d, d1)
  1309. def test_classic(self):
  1310. # Testing classic classes...
  1311. class C:
  1312. def foo(*a): return a
  1313. goo = classmethod(foo)
  1314. c = C()
  1315. self.assertEqual(C.goo(1), (C, 1))
  1316. self.assertEqual(c.goo(1), (C, 1))
  1317. self.assertEqual(c.foo(1), (c, 1))
  1318. class D(C):
  1319. pass
  1320. d = D()
  1321. self.assertEqual(D.goo(1), (D, 1))
  1322. self.assertEqual(d.goo(1), (D, 1))
  1323. self.assertEqual(d.foo(1), (d, 1))
  1324. self.assertEqual(D.foo(d, 1), (d, 1))
  1325. class E: # *not* subclassing from C
  1326. foo = C.foo
  1327. self.assertEqual(E().foo, C.foo) # i.e., unbound
  1328. self.assert_(repr(C.foo.__get__(C())).startswith("<bound method "))
  1329. def test_compattr(self):
  1330. # Testing computed attributes...
  1331. class C(object):
  1332. class computed_attribute(object):
  1333. def __init__(self, get, set=None, delete=None):
  1334. self.__get = get
  1335. self.__set = set
  1336. self.__delete = delete
  1337. def __get__(self, obj, type=None):
  1338. return self.__get(obj)
  1339. def __set__(self, obj, value):
  1340. return self.__set(obj, value)
  1341. def __delete__(self, obj):
  1342. return self.__delete(obj)
  1343. def __init__(self):
  1344. self.__x = 0
  1345. def __get_x(self):
  1346. x = self.__x
  1347. self.__x = x+1
  1348. return x
  1349. def __set_x(self, x):
  1350. self.__x = x
  1351. def __delete_x(self):
  1352. del self.__x
  1353. x = computed_attribute(__get_x, __set_x, __delete_x)
  1354. a = C()
  1355. self.assertEqual(a.x, 0)
  1356. self.assertEqual(a.x, 1)
  1357. a.x = 10
  1358. self.assertEqual(a.x, 10)
  1359. self.assertEqual(a.x, 11)
  1360. del a.x
  1361. self.assertEqual(hasattr(a, 'x'), 0)
  1362. def test_newslots(self):
  1363. # Testing __new__ slot override...
  1364. class C(list):
  1365. def __new__(cls):
  1366. self = list.__new__(cls)
  1367. self.foo = 1
  1368. return self
  1369. def __init__(self):
  1370. self.foo = self.foo + 2
  1371. a = C()
  1372. self.assertEqual(a.foo, 3)
  1373. self.assertEqual(a.__class__, C)
  1374. class D(C):
  1375. pass
  1376. b = D()
  1377. self.assertEqual(b.foo, 3)
  1378. self.assertEqual(b.__class__, D)
  1379. def test_altmro(self):
  1380. # Testing mro() and overriding it...
  1381. class A(object):
  1382. def f(self): return "A"
  1383. class B(A):
  1384. pass
  1385. class C(A):
  1386. def f(self): return "C"
  1387. class D(B, C):
  1388. pass
  1389. self.assertEqual(D.mro(), [D, B, C, A, object])
  1390. self.assertEqual(D.__mro__, (D, B, C, A, object))
  1391. self.assertEqual(D().f(), "C")
  1392. class PerverseMetaType(type):
  1393. def mro(cls):
  1394. L = type.mro(cls)
  1395. L.reverse()
  1396. return L
  1397. class X(D,B,C,A):
  1398. __metaclass__ = PerverseMetaType
  1399. self.assertEqual(X.__mro__, (object, A, C, B, D, X))
  1400. self.assertEqual(X().f(), "A")
  1401. try:
  1402. class X(object):
  1403. class __metaclass__(type):