test_super.py 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. """Unit tests for zero-argument super() & related machinery."""
  2. import unittest
  3. class A:
  4. def f(self):
  5. return 'A'
  6. @classmethod
  7. def cm(cls):
  8. return (cls, 'A')
  9. class B(A):
  10. def f(self):
  11. return super().f() + 'B'
  12. @classmethod
  13. def cm(cls):
  14. return (cls, super().cm(), 'B')
  15. class C(A):
  16. def f(self):
  17. return super().f() + 'C'
  18. @classmethod
  19. def cm(cls):
  20. return (cls, super().cm(), 'C')
  21. class D(C, B):
  22. def f(self):
  23. return super().f() + 'D'
  24. def cm(cls):
  25. return (cls, super().cm(), 'D')
  26. class E(D):
  27. pass
  28. class F(E):
  29. f = E.f
  30. class G(A):
  31. pass
  32. class TestSuper(unittest.TestCase):
  33. def tearDown(self):
  34. # This fixes the damage that test_various___class___pathologies does.
  35. nonlocal __class__
  36. __class__ = TestSuper
  37. def test_basics_working(self):
  38. self.assertEqual(D().f(), 'ABCD')
  39. def test_class_getattr_working(self):
  40. self.assertEqual(D.f(D()), 'ABCD')
  41. def test_subclass_no_override_working(self):
  42. self.assertEqual(E().f(), 'ABCD')
  43. self.assertEqual(E.f(E()), 'ABCD')
  44. def test_unbound_method_transfer_working(self):
  45. self.assertEqual(F().f(), 'ABCD')
  46. self.assertEqual(F.f(F()), 'ABCD')
  47. def test_class_methods_still_working(self):
  48. self.assertEqual(A.cm(), (A, 'A'))
  49. self.assertEqual(A().cm(), (A, 'A'))
  50. self.assertEqual(G.cm(), (G, 'A'))
  51. self.assertEqual(G().cm(), (G, 'A'))
  52. def test_super_in_class_methods_working(self):
  53. d = D()
  54. self.assertEqual(d.cm(), (d, (D, (D, (D, 'A'), 'B'), 'C'), 'D'))
  55. e = E()
  56. self.assertEqual(e.cm(), (e, (E, (E, (E, 'A'), 'B'), 'C'), 'D'))
  57. def test_super_with_closure(self):
  58. # Issue4360: super() did not work in a function that
  59. # contains a closure
  60. class E(A):
  61. def f(self):
  62. def nested():
  63. self
  64. return super().f() + 'E'
  65. self.assertEqual(E().f(), 'AE')
  66. def test_various___class___pathologies(self):
  67. # See issue #12370
  68. class X(A):
  69. def f(self):
  70. return super().f()
  71. __class__ = 413
  72. x = X()
  73. self.assertEqual(x.f(), 'A')
  74. self.assertEqual(x.__class__, 413)
  75. class X:
  76. x = __class__
  77. def f():
  78. __class__
  79. self.assertIs(X.x, type(self))
  80. with self.assertRaises(NameError) as e:
  81. exec("""class X:
  82. __class__
  83. def f():
  84. __class__""", globals(), {})
  85. self.assertIs(type(e.exception), NameError) # Not UnboundLocalError
  86. class X:
  87. global __class__
  88. __class__ = 42
  89. def f():
  90. __class__
  91. self.assertEqual(globals()["__class__"], 42)
  92. del globals()["__class__"]
  93. self.assertNotIn("__class__", X.__dict__)
  94. class X:
  95. nonlocal __class__
  96. __class__ = 42
  97. def f():
  98. __class__
  99. self.assertEqual(__class__, 42)
  100. def test___class___instancemethod(self):
  101. # See issue #14857
  102. class X:
  103. def f(self):
  104. return __class__
  105. self.assertIs(X().f(), X)
  106. def test___class___classmethod(self):
  107. # See issue #14857
  108. class X:
  109. @classmethod
  110. def f(cls):
  111. return __class__
  112. self.assertIs(X.f(), X)
  113. def test___class___staticmethod(self):
  114. # See issue #14857
  115. class X:
  116. @staticmethod
  117. def f():
  118. return __class__
  119. self.assertIs(X.f(), X)
  120. def test___class___new(self):
  121. # See issue #23722
  122. # Ensure zero-arg super() works as soon as type.__new__() is completed
  123. test_class = None
  124. class Meta(type):
  125. def __new__(cls, name, bases, namespace):
  126. nonlocal test_class
  127. self = super().__new__(cls, name, bases, namespace)
  128. test_class = self.f()
  129. return self
  130. class A(metaclass=Meta):
  131. @staticmethod
  132. def f():
  133. return __class__
  134. self.assertIs(test_class, A)
  135. def test___class___delayed(self):
  136. # See issue #23722
  137. test_namespace = None
  138. class Meta(type):
  139. def __new__(cls, name, bases, namespace):
  140. nonlocal test_namespace
  141. test_namespace = namespace
  142. return None
  143. class A(metaclass=Meta):
  144. @staticmethod
  145. def f():
  146. return __class__
  147. self.assertIs(A, None)
  148. B = type("B", (), test_namespace)
  149. self.assertIs(B.f(), B)
  150. def test___class___mro(self):
  151. # See issue #23722
  152. test_class = None
  153. class Meta(type):
  154. def mro(self):
  155. # self.f() doesn't work yet...
  156. self.__dict__["f"]()
  157. return super().mro()
  158. class A(metaclass=Meta):
  159. def f():
  160. nonlocal test_class
  161. test_class = __class__
  162. self.assertIs(test_class, A)
  163. def test___classcell___expected_behaviour(self):
  164. # See issue #23722
  165. class Meta(type):
  166. def __new__(cls, name, bases, namespace):
  167. nonlocal namespace_snapshot
  168. namespace_snapshot = namespace.copy()
  169. return super().__new__(cls, name, bases, namespace)
  170. # __classcell__ is injected into the class namespace by the compiler
  171. # when at least one method needs it, and should be omitted otherwise
  172. namespace_snapshot = None
  173. class WithoutClassRef(metaclass=Meta):
  174. pass
  175. self.assertNotIn("__classcell__", namespace_snapshot)
  176. # With zero-arg super() or an explicit __class__ reference,
  177. # __classcell__ is the exact cell reference to be populated by
  178. # type.__new__
  179. namespace_snapshot = None
  180. class WithClassRef(metaclass=Meta):
  181. def f(self):
  182. return __class__
  183. class_cell = namespace_snapshot["__classcell__"]
  184. method_closure = WithClassRef.f.__closure__
  185. self.assertEqual(len(method_closure), 1)
  186. self.assertIs(class_cell, method_closure[0])
  187. # Ensure the cell reference *doesn't* get turned into an attribute
  188. with self.assertRaises(AttributeError):
  189. WithClassRef.__classcell__
  190. def test___classcell___missing(self):
  191. # See issue #23722
  192. # Some metaclasses may not pass the original namespace to type.__new__
  193. # We test that case here by forcibly deleting __classcell__
  194. class Meta(type):
  195. def __new__(cls, name, bases, namespace):
  196. namespace.pop('__classcell__', None)
  197. return super().__new__(cls, name, bases, namespace)
  198. # The default case should continue to work without any errors
  199. class WithoutClassRef(metaclass=Meta):
  200. pass
  201. # With zero-arg super() or an explicit __class__ reference, we expect
  202. # __build_class__ to raise a RuntimeError complaining that
  203. # __class__ was not set, and asking if __classcell__ was propagated
  204. # to type.__new__.
  205. expected_error = '__class__ not set.*__classcell__ propagated'
  206. with self.assertRaisesRegex(RuntimeError, expected_error):
  207. class WithClassRef(metaclass=Meta):
  208. def f(self):
  209. return __class__
  210. def test___classcell___overwrite(self):
  211. # See issue #23722
  212. # Overwriting __classcell__ with nonsense is explicitly prohibited
  213. class Meta(type):
  214. def __new__(cls, name, bases, namespace, cell):
  215. namespace['__classcell__'] = cell
  216. return super().__new__(cls, name, bases, namespace)
  217. for bad_cell in (None, 0, "", object()):
  218. with self.subTest(bad_cell=bad_cell):
  219. with self.assertRaises(TypeError):
  220. class A(metaclass=Meta, cell=bad_cell):
  221. pass
  222. def test___classcell___wrong_cell(self):
  223. # See issue #23722
  224. # Pointing the cell reference at the wrong class is also prohibited
  225. class Meta(type):
  226. def __new__(cls, name, bases, namespace):
  227. cls = super().__new__(cls, name, bases, namespace)
  228. B = type("B", (), namespace)
  229. return cls
  230. with self.assertRaises(TypeError):
  231. class A(metaclass=Meta):
  232. def f(self):
  233. return __class__
  234. def test_obscure_super_errors(self):
  235. def f():
  236. super()
  237. self.assertRaises(RuntimeError, f)
  238. def f(x):
  239. del x
  240. super()
  241. self.assertRaises(RuntimeError, f, None)
  242. class X:
  243. def f(x):
  244. nonlocal __class__
  245. del __class__
  246. super()
  247. self.assertRaises(RuntimeError, X().f)
  248. def test_cell_as_self(self):
  249. class X:
  250. def meth(self):
  251. super()
  252. def f():
  253. k = X()
  254. def g():
  255. return k
  256. return g
  257. c = f().__closure__[0]
  258. self.assertRaises(TypeError, X.meth, c)
  259. def test_super_init_leaks(self):
  260. # Issue #26718: super.__init__ leaked memory if called multiple times.
  261. # This will be caught by regrtest.py -R if this leak.
  262. # NOTE: Despite the use in the test a direct call of super.__init__
  263. # is not endorsed.
  264. sp = super(float, 1.0)
  265. for i in range(1000):
  266. super.__init__(sp, int, i)
  267. def test_super_argcount(self):
  268. with self.assertRaisesRegex(TypeError, "expected at most"):
  269. super(int, int, int)
  270. def test_super_argtype(self):
  271. with self.assertRaisesRegex(TypeError, "argument 1 must be a type"):
  272. super(1, int)
  273. if __name__ == "__main__":
  274. unittest.main()