blob: 37fc2d913417c454d011a8459b32b791f7cf3cd4 [file] [log] [blame]
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001"""Unit tests for new super() implementation."""
2
3import sys
4import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00005from test import support
Guido van Rossumcd16bf62007-06-13 18:07:49 +00006
7
8class A:
9 def f(self):
10 return 'A'
11 @classmethod
12 def cm(cls):
13 return (cls, 'A')
14
15class B(A):
16 def f(self):
17 return super().f() + 'B'
18 @classmethod
19 def cm(cls):
20 return (cls, super().cm(), 'B')
21
22class C(A):
23 def f(self):
24 return super().f() + 'C'
25 @classmethod
26 def cm(cls):
27 return (cls, super().cm(), 'C')
28
29class D(C, B):
30 def f(self):
31 return super().f() + 'D'
32 def cm(cls):
33 return (cls, super().cm(), 'D')
34
35class E(D):
36 pass
37
38class F(E):
39 f = E.f
40
41class G(A):
42 pass
43
44
45class TestSuper(unittest.TestCase):
46
Benjamin Petersona29ac452013-05-17 11:33:26 -050047 def tearDown(self):
48 # This fixes the damage that test_various___class___pathologies does.
49 nonlocal __class__
50 __class__ = TestSuper
51
Benjamin Peterson206cd1c2011-06-19 17:49:13 -050052 def test_basics_working(self):
Guido van Rossumcd16bf62007-06-13 18:07:49 +000053 self.assertEqual(D().f(), 'ABCD')
54
Benjamin Peterson206cd1c2011-06-19 17:49:13 -050055 def test_class_getattr_working(self):
Guido van Rossumcd16bf62007-06-13 18:07:49 +000056 self.assertEqual(D.f(D()), 'ABCD')
57
Benjamin Peterson206cd1c2011-06-19 17:49:13 -050058 def test_subclass_no_override_working(self):
Guido van Rossumcd16bf62007-06-13 18:07:49 +000059 self.assertEqual(E().f(), 'ABCD')
60 self.assertEqual(E.f(E()), 'ABCD')
61
Benjamin Peterson206cd1c2011-06-19 17:49:13 -050062 def test_unbound_method_transfer_working(self):
Guido van Rossumcd16bf62007-06-13 18:07:49 +000063 self.assertEqual(F().f(), 'ABCD')
64 self.assertEqual(F.f(F()), 'ABCD')
65
Benjamin Peterson206cd1c2011-06-19 17:49:13 -050066 def test_class_methods_still_working(self):
Guido van Rossumcd16bf62007-06-13 18:07:49 +000067 self.assertEqual(A.cm(), (A, 'A'))
68 self.assertEqual(A().cm(), (A, 'A'))
69 self.assertEqual(G.cm(), (G, 'A'))
70 self.assertEqual(G().cm(), (G, 'A'))
71
Benjamin Peterson206cd1c2011-06-19 17:49:13 -050072 def test_super_in_class_methods_working(self):
Guido van Rossumcd16bf62007-06-13 18:07:49 +000073 d = D()
74 self.assertEqual(d.cm(), (d, (D, (D, (D, 'A'), 'B'), 'C'), 'D'))
75 e = E()
76 self.assertEqual(e.cm(), (e, (E, (E, (E, 'A'), 'B'), 'C'), 'D'))
77
Benjamin Peterson206cd1c2011-06-19 17:49:13 -050078 def test_super_with_closure(self):
Barry Warsaw91cc8fb2008-11-20 20:01:57 +000079 # Issue4360: super() did not work in a function that
80 # contains a closure
81 class E(A):
82 def f(self):
83 def nested():
84 self
85 return super().f() + 'E'
86
87 self.assertEqual(E().f(), 'AE')
88
Benjamin Peterson312595c2013-05-15 15:26:42 -050089 def test_various___class___pathologies(self):
Benjamin Petersonf5ff2232011-06-19 19:42:22 -050090 # See issue #12370
91 class X(A):
92 def f(self):
93 return super().f()
94 __class__ = 413
95 x = X()
96 self.assertEqual(x.f(), 'A')
97 self.assertEqual(x.__class__, 413)
Benjamin Peterson312595c2013-05-15 15:26:42 -050098 class X:
99 x = __class__
100 def f():
101 __class__
102 self.assertIs(X.x, type(self))
103 with self.assertRaises(NameError) as e:
104 exec("""class X:
105 __class__
106 def f():
107 __class__""", globals(), {})
108 self.assertIs(type(e.exception), NameError) # Not UnboundLocalError
109 class X:
110 global __class__
111 __class__ = 42
112 def f():
113 __class__
114 self.assertEqual(globals()["__class__"], 42)
115 del globals()["__class__"]
116 self.assertNotIn("__class__", X.__dict__)
117 class X:
118 nonlocal __class__
119 __class__ = 42
120 def f():
121 __class__
122 self.assertEqual(__class__, 42)
Benjamin Petersonf5ff2232011-06-19 19:42:22 -0500123
Nick Coghlan0b43bcf2012-05-27 18:17:07 +1000124 def test___class___instancemethod(self):
125 # See issue #14857
126 class X:
127 def f(self):
128 return __class__
129 self.assertIs(X().f(), X)
130
131 def test___class___classmethod(self):
132 # See issue #14857
133 class X:
134 @classmethod
135 def f(cls):
136 return __class__
137 self.assertIs(X.f(), X)
138
139 def test___class___staticmethod(self):
140 # See issue #14857
141 class X:
142 @staticmethod
143 def f():
144 return __class__
145 self.assertIs(X.f(), X)
146
Benjamin Peterson6a42bd62012-09-01 23:04:38 -0400147 def test_obscure_super_errors(self):
148 def f():
149 super()
150 self.assertRaises(RuntimeError, f)
151 def f(x):
152 del x
153 super()
154 self.assertRaises(RuntimeError, f, None)
155 class X:
156 def f(x):
157 nonlocal __class__
158 del __class__
159 super()
160 self.assertRaises(RuntimeError, X().f)
161
Benjamin Peterson159ae412013-05-12 18:16:06 -0500162 def test_cell_as_self(self):
163 class X:
164 def meth(self):
165 super()
166
167 def f():
168 k = X()
169 def g():
170 return k
171 return g
172 c = f().__closure__[0]
173 self.assertRaises(TypeError, X.meth, c)
174
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000175
176def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000177 support.run_unittest(TestSuper)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000178
179
180if __name__ == "__main__":
181 unittest.main()