blob: b84863fe53c6ec5e13f6625acdbe0dd39df13c98 [file] [log] [blame]
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001"""Unit tests for new super() implementation."""
2
3import sys
4import unittest
Guido van Rossumcd16bf62007-06-13 18:07:49 +00005
6
7class A:
8 def f(self):
9 return 'A'
10 @classmethod
11 def cm(cls):
12 return (cls, 'A')
13
14class B(A):
15 def f(self):
16 return super().f() + 'B'
17 @classmethod
18 def cm(cls):
19 return (cls, super().cm(), 'B')
20
21class C(A):
22 def f(self):
23 return super().f() + 'C'
24 @classmethod
25 def cm(cls):
26 return (cls, super().cm(), 'C')
27
28class D(C, B):
29 def f(self):
30 return super().f() + 'D'
31 def cm(cls):
32 return (cls, super().cm(), 'D')
33
34class E(D):
35 pass
36
37class F(E):
38 f = E.f
39
40class G(A):
41 pass
42
43
44class TestSuper(unittest.TestCase):
45
Benjamin Petersona29ac452013-05-17 11:33:26 -050046 def tearDown(self):
47 # This fixes the damage that test_various___class___pathologies does.
48 nonlocal __class__
49 __class__ = TestSuper
50
Benjamin Peterson206cd1c2011-06-19 17:49:13 -050051 def test_basics_working(self):
Guido van Rossumcd16bf62007-06-13 18:07:49 +000052 self.assertEqual(D().f(), 'ABCD')
53
Benjamin Peterson206cd1c2011-06-19 17:49:13 -050054 def test_class_getattr_working(self):
Guido van Rossumcd16bf62007-06-13 18:07:49 +000055 self.assertEqual(D.f(D()), 'ABCD')
56
Benjamin Peterson206cd1c2011-06-19 17:49:13 -050057 def test_subclass_no_override_working(self):
Guido van Rossumcd16bf62007-06-13 18:07:49 +000058 self.assertEqual(E().f(), 'ABCD')
59 self.assertEqual(E.f(E()), 'ABCD')
60
Benjamin Peterson206cd1c2011-06-19 17:49:13 -050061 def test_unbound_method_transfer_working(self):
Guido van Rossumcd16bf62007-06-13 18:07:49 +000062 self.assertEqual(F().f(), 'ABCD')
63 self.assertEqual(F.f(F()), 'ABCD')
64
Benjamin Peterson206cd1c2011-06-19 17:49:13 -050065 def test_class_methods_still_working(self):
Guido van Rossumcd16bf62007-06-13 18:07:49 +000066 self.assertEqual(A.cm(), (A, 'A'))
67 self.assertEqual(A().cm(), (A, 'A'))
68 self.assertEqual(G.cm(), (G, 'A'))
69 self.assertEqual(G().cm(), (G, 'A'))
70
Benjamin Peterson206cd1c2011-06-19 17:49:13 -050071 def test_super_in_class_methods_working(self):
Guido van Rossumcd16bf62007-06-13 18:07:49 +000072 d = D()
73 self.assertEqual(d.cm(), (d, (D, (D, (D, 'A'), 'B'), 'C'), 'D'))
74 e = E()
75 self.assertEqual(e.cm(), (e, (E, (E, (E, 'A'), 'B'), 'C'), 'D'))
76
Benjamin Peterson206cd1c2011-06-19 17:49:13 -050077 def test_super_with_closure(self):
Barry Warsaw91cc8fb2008-11-20 20:01:57 +000078 # Issue4360: super() did not work in a function that
79 # contains a closure
80 class E(A):
81 def f(self):
82 def nested():
83 self
84 return super().f() + 'E'
85
86 self.assertEqual(E().f(), 'AE')
87
Benjamin Peterson312595c2013-05-15 15:26:42 -050088 def test_various___class___pathologies(self):
Benjamin Petersonf5ff2232011-06-19 19:42:22 -050089 # See issue #12370
90 class X(A):
91 def f(self):
92 return super().f()
93 __class__ = 413
94 x = X()
95 self.assertEqual(x.f(), 'A')
96 self.assertEqual(x.__class__, 413)
Benjamin Peterson312595c2013-05-15 15:26:42 -050097 class X:
98 x = __class__
99 def f():
100 __class__
101 self.assertIs(X.x, type(self))
102 with self.assertRaises(NameError) as e:
103 exec("""class X:
104 __class__
105 def f():
106 __class__""", globals(), {})
107 self.assertIs(type(e.exception), NameError) # Not UnboundLocalError
108 class X:
109 global __class__
110 __class__ = 42
111 def f():
112 __class__
113 self.assertEqual(globals()["__class__"], 42)
114 del globals()["__class__"]
115 self.assertNotIn("__class__", X.__dict__)
116 class X:
117 nonlocal __class__
118 __class__ = 42
119 def f():
120 __class__
121 self.assertEqual(__class__, 42)
Benjamin Petersonf5ff2232011-06-19 19:42:22 -0500122
Nick Coghlan0b43bcf2012-05-27 18:17:07 +1000123 def test___class___instancemethod(self):
124 # See issue #14857
125 class X:
126 def f(self):
127 return __class__
128 self.assertIs(X().f(), X)
129
130 def test___class___classmethod(self):
131 # See issue #14857
132 class X:
133 @classmethod
134 def f(cls):
135 return __class__
136 self.assertIs(X.f(), X)
137
138 def test___class___staticmethod(self):
139 # See issue #14857
140 class X:
141 @staticmethod
142 def f():
143 return __class__
144 self.assertIs(X.f(), X)
145
Benjamin Peterson6a42bd62012-09-01 23:04:38 -0400146 def test_obscure_super_errors(self):
147 def f():
148 super()
149 self.assertRaises(RuntimeError, f)
150 def f(x):
151 del x
152 super()
153 self.assertRaises(RuntimeError, f, None)
154 class X:
155 def f(x):
156 nonlocal __class__
157 del __class__
158 super()
159 self.assertRaises(RuntimeError, X().f)
160
Benjamin Peterson159ae412013-05-12 18:16:06 -0500161 def test_cell_as_self(self):
162 class X:
163 def meth(self):
164 super()
165
166 def f():
167 k = X()
168 def g():
169 return k
170 return g
171 c = f().__closure__[0]
172 self.assertRaises(TypeError, X.meth, c)
173
Serhiy Storchaka3d749762016-04-13 15:27:33 +0300174 def test_super_init_leaks(self):
175 # Issue #26718: super.__init__ leaked memory if called multiple times.
176 # This will be caught by regrtest.py -R if this leak.
177 # NOTE: Despite the use in the test a direct call of super.__init__
178 # is not endorsed.
179 sp = super(float, 1.0)
180 for i in range(1000):
181 super.__init__(sp, int, i)
182
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000183
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000184if __name__ == "__main__":
185 unittest.main()