Skip to content

Commit 9250e22

Browse files
committed
Add super() tests from magicsuper and Py3.3
1 parent 2bda2af commit 9250e22

File tree

2 files changed

+283
-0
lines changed

2 files changed

+283
-0
lines changed

future/tests/test_magicsuper.py

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
"""
2+
Tests for the super() function.
3+
4+
Based on Ryan Kelly's magicsuper.tests
5+
"""
6+
7+
from __future__ import absolute_import, division, print_function, unicode_literals
8+
import future.builtins.newsuper
9+
from future.builtins import super
10+
from future.tests.base import unittest
11+
from future.utils import PY2
12+
13+
14+
class TestMagicSuper(unittest.TestCase):
15+
16+
def test_basic_diamond(self):
17+
class Base(object):
18+
def calc(self,value):
19+
return 2 * value
20+
class Sub1(Base):
21+
def calc(self,value):
22+
return 7 + super().calc(value)
23+
class Sub2(Base):
24+
def calc(self,value):
25+
return super().calc(value) - 1
26+
class Diamond(Sub1,Sub2):
27+
def calc(self,value):
28+
return 3 * super().calc(value)
29+
b = Base()
30+
s1 = Sub1()
31+
s2 = Sub2()
32+
d = Diamond()
33+
for x in range(10):
34+
self.assertEquals(b.calc(x),2*x)
35+
self.assertEquals(s1.calc(x),7+(2*x))
36+
self.assertEquals(s2.calc(x),(2*x)-1)
37+
self.assertEquals(d.calc(x),3*(7+((2*x)-1)))
38+
39+
def test_with_unrelated_methods(self):
40+
class Base(object):
41+
def hello(self):
42+
return "world"
43+
class Sub(Base):
44+
def hello(self):
45+
return "hello " + super().hello()
46+
def other(self):
47+
pass
48+
class SubSub(Sub):
49+
def other(self):
50+
return super().other()
51+
ss = SubSub()
52+
self.assertEquals(ss.hello(),"hello world")
53+
54+
def test_fails_for_oldstyle_class(self):
55+
class OldStyle:
56+
def testme(self):
57+
return super().testme()
58+
o = OldStyle()
59+
self.assertRaises(RuntimeError,o.testme)
60+
61+
def test_fails_for_raw_functions(self):
62+
def not_a_method():
63+
super().not_a_method()
64+
self.assertRaises(RuntimeError,not_a_method)
65+
def not_a_method(self):
66+
super().not_a_method()
67+
self.assertRaises(RuntimeError,not_a_method,self)
68+
69+
def assertSuperEquals(self,sobj1,sobj2):
70+
assert sobj1.__self__ is sobj2.__self__
71+
assert sobj1.__self_class__ is sobj2.__self_class__
72+
assert sobj1.__thisclass__ is sobj2.__thisclass__
73+
74+
def test_call_with_args_does_nothing(self):
75+
if PY2:
76+
from __builtin__ import super as builtin_super
77+
else:
78+
from builtins import super as builtin_super
79+
class Base(object):
80+
def calc(self,value):
81+
return 2 * value
82+
class Sub1(Base):
83+
def calc(self,value):
84+
return 7 + super().calc(value)
85+
class Sub2(Base):
86+
def calc(self,value):
87+
return super().calc(value) - 1
88+
class Diamond(Sub1,Sub2):
89+
def calc(self,value):
90+
return 3 * super().calc(value)
91+
for cls in (Base,Sub1,Sub2,Diamond,):
92+
obj = cls()
93+
self.assertSuperEquals(builtin_super(cls), super(cls))
94+
self.assertSuperEquals(builtin_super(cls,obj), super(cls,obj))
95+
96+
def test_superm(self):
97+
class Base(object):
98+
def getit(self):
99+
return 2
100+
class Sub(Base):
101+
def getit(self):
102+
return 10 * future.builtins.newsuper.superm()
103+
s = Sub()
104+
self.assertEquals(s.getit(),20)
105+
106+
def test_use_inside_dunder_new(self):
107+
class Terminal(str):
108+
def __new__(cls, value, token_type):
109+
self = super().__new__(cls, value)
110+
self.token_type = token_type
111+
return self
112+
DOT = Terminal(".", "dit")
113+
self.assertTrue(isinstance(DOT, str))
114+
self.assertTrue(isinstance(DOT, Terminal))
115+
116+
def test_use_inside_classmethod(self):
117+
class Base(object):
118+
@classmethod
119+
def getit(cls):
120+
return 42
121+
class Singleton(Base):
122+
@classmethod
123+
def getit(cls):
124+
print(super())
125+
return super().getit() + 1
126+
self.assertEquals(Singleton.getit(), 43)
127+
128+
129+
if __name__ == '__main__':
130+
unittest.main()
131+

future/tests/test_super.py

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
"""Unit tests for new super() implementation."""
2+
3+
import sys
4+
import unittest
5+
from test import support
6+
7+
8+
class A:
9+
def f(self):
10+
return 'A'
11+
@classmethod
12+
def cm(cls):
13+
return (cls, 'A')
14+
15+
class B(A):
16+
def f(self):
17+
return super().f() + 'B'
18+
@classmethod
19+
def cm(cls):
20+
return (cls, super().cm(), 'B')
21+
22+
class C(A):
23+
def f(self):
24+
return super().f() + 'C'
25+
@classmethod
26+
def cm(cls):
27+
return (cls, super().cm(), 'C')
28+
29+
class D(C, B):
30+
def f(self):
31+
return super().f() + 'D'
32+
def cm(cls):
33+
return (cls, super().cm(), 'D')
34+
35+
class E(D):
36+
pass
37+
38+
class F(E):
39+
f = E.f
40+
41+
class G(A):
42+
pass
43+
44+
45+
class TestSuper(unittest.TestCase):
46+
47+
def test_basics_working(self):
48+
self.assertEqual(D().f(), 'ABCD')
49+
50+
def test_class_getattr_working(self):
51+
self.assertEqual(D.f(D()), 'ABCD')
52+
53+
def test_subclass_no_override_working(self):
54+
self.assertEqual(E().f(), 'ABCD')
55+
self.assertEqual(E.f(E()), 'ABCD')
56+
57+
def test_unbound_method_transfer_working(self):
58+
self.assertEqual(F().f(), 'ABCD')
59+
self.assertEqual(F.f(F()), 'ABCD')
60+
61+
def test_class_methods_still_working(self):
62+
self.assertEqual(A.cm(), (A, 'A'))
63+
self.assertEqual(A().cm(), (A, 'A'))
64+
self.assertEqual(G.cm(), (G, 'A'))
65+
self.assertEqual(G().cm(), (G, 'A'))
66+
67+
def test_super_in_class_methods_working(self):
68+
d = D()
69+
self.assertEqual(d.cm(), (d, (D, (D, (D, 'A'), 'B'), 'C'), 'D'))
70+
e = E()
71+
self.assertEqual(e.cm(), (e, (E, (E, (E, 'A'), 'B'), 'C'), 'D'))
72+
73+
def test_super_with_closure(self):
74+
# Issue4360: super() did not work in a function that
75+
# contains a closure
76+
class E(A):
77+
def f(self):
78+
def nested():
79+
self
80+
return super().f() + 'E'
81+
82+
self.assertEqual(E().f(), 'AE')
83+
84+
@unittest.expectedFailure
85+
def test___class___set(self):
86+
# See issue #12370
87+
class X(A):
88+
def f(self):
89+
return super().f()
90+
__class__ = 413
91+
x = X()
92+
self.assertEqual(x.f(), 'A')
93+
self.assertEqual(x.__class__, 413)
94+
95+
def test___class___instancemethod(self):
96+
# See issue #14857
97+
class X:
98+
def f(self):
99+
return __class__
100+
self.assertIs(X().f(), X)
101+
102+
def test___class___classmethod(self):
103+
# See issue #14857
104+
class X:
105+
@classmethod
106+
def f(cls):
107+
return __class__
108+
self.assertIs(X.f(), X)
109+
110+
def test___class___staticmethod(self):
111+
# See issue #14857
112+
class X:
113+
@staticmethod
114+
def f():
115+
return __class__
116+
self.assertIs(X.f(), X)
117+
118+
def test_obscure_super_errors(self):
119+
def f():
120+
super()
121+
self.assertRaises(RuntimeError, f)
122+
def f(x):
123+
del x
124+
super()
125+
self.assertRaises(RuntimeError, f, None)
126+
class X:
127+
def f(x):
128+
nonlocal __class__
129+
del __class__
130+
super()
131+
self.assertRaises(RuntimeError, X().f)
132+
133+
def test_cell_as_self(self):
134+
class X:
135+
def meth(self):
136+
super()
137+
138+
def f():
139+
k = X()
140+
def g():
141+
return k
142+
return g
143+
c = f().__closure__[0]
144+
self.assertRaises(TypeError, X.meth, c)
145+
146+
147+
def test_main():
148+
support.run_unittest(TestSuper)
149+
150+
151+
if __name__ == "__main__":
152+
unittest.main()

0 commit comments

Comments
 (0)