Skip to content

Commit e580908

Browse files
committed
Update super() tests with more from Py3.3
1 parent 969bd45 commit e580908

File tree

1 file changed

+191
-16
lines changed

1 file changed

+191
-16
lines changed

future/tests/test_super.py

Lines changed: 191 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import unittest
66

77
from future.tests.base import unittest
8+
from future import utils
89
from future.builtins import super
910

1011

@@ -84,24 +85,26 @@ def nested():
8485

8586
self.assertEqual(E().f(), 'AE')
8687

87-
@unittest.expectedFailure
88-
def test___class___set(self):
89-
# 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)
88+
# We declare this test invalid: __class__ should be a class.
89+
# def test___class___set(self):
90+
# # 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)
9798

99+
@unittest.skipIf(utils.PY2, "no __class__ on Py2")
98100
def test___class___instancemethod(self):
99101
# See issue #14857
100102
class X(object):
101103
def f(self):
102104
return __class__
103105
self.assertIs(X().f(), X)
104106

107+
@unittest.skipIf(utils.PY2, "no __class__ on Py2")
105108
def test___class___classmethod(self):
106109
# See issue #14857
107110
class X(object):
@@ -110,6 +113,7 @@ def f(cls):
110113
return __class__
111114
self.assertIs(X.f(), X)
112115

116+
@unittest.skipIf(utils.PY2, "no __class__ on Py2")
113117
def test___class___staticmethod(self):
114118
# See issue #14857
115119
class X(object):
@@ -126,12 +130,12 @@ def f(x):
126130
del x
127131
super()
128132
self.assertRaises(RuntimeError, f, None)
129-
class X(object):
130-
def f(x):
131-
# nonlocal __class__
132-
del __class__
133-
super()
134-
self.assertRaises(RuntimeError, X().f)
133+
# class X(object):
134+
# def f(x):
135+
# nonlocal __class__
136+
# del __class__
137+
# super()
138+
# self.assertRaises(RuntimeError, X().f)
135139

136140
def test_cell_as_self(self):
137141
class X(object):
@@ -147,5 +151,176 @@ def g():
147151
self.assertRaises(TypeError, X.meth, c)
148152

149153

154+
class TestSuperFromTestDescrDotPy(unittest.TestCase):
155+
"""
156+
These are from Python 3.3.5/Lib/test/test_descr.py
157+
"""
158+
def test_classmethods(self):
159+
# Testing class methods...
160+
class C(object):
161+
def foo(*a): return a
162+
goo = classmethod(foo)
163+
c = C()
164+
self.assertEqual(C.goo(1), (C, 1))
165+
self.assertEqual(c.goo(1), (C, 1))
166+
self.assertEqual(c.foo(1), (c, 1))
167+
class D(C):
168+
pass
169+
d = D()
170+
self.assertEqual(D.goo(1), (D, 1))
171+
self.assertEqual(d.goo(1), (D, 1))
172+
self.assertEqual(d.foo(1), (d, 1))
173+
self.assertEqual(D.foo(d, 1), (d, 1))
174+
# Test for a specific crash (SF bug 528132)
175+
def f(cls, arg): return (cls, arg)
176+
ff = classmethod(f)
177+
self.assertEqual(ff.__get__(0, int)(42), (int, 42))
178+
self.assertEqual(ff.__get__(0)(42), (int, 42))
179+
180+
# Test super() with classmethods (SF bug 535444)
181+
self.assertEqual(C.goo.__self__, C)
182+
self.assertEqual(D.goo.__self__, D)
183+
self.assertEqual(super(D,D).goo.__self__, D)
184+
self.assertEqual(super(D,d).goo.__self__, D)
185+
self.assertEqual(super(D,D).goo(), (D,))
186+
self.assertEqual(super(D,d).goo(), (D,))
187+
188+
# Verify that a non-callable will raise
189+
meth = classmethod(1).__get__(1)
190+
self.assertRaises(TypeError, meth)
191+
192+
# Verify that classmethod() doesn't allow keyword args
193+
try:
194+
classmethod(f, kw=1)
195+
except TypeError:
196+
pass
197+
else:
198+
self.fail("classmethod shouldn't accept keyword args")
199+
200+
# cm = classmethod(f)
201+
# self.assertEqual(cm.__dict__, {})
202+
# cm.x = 42
203+
# self.assertEqual(cm.x, 42)
204+
# self.assertEqual(cm.__dict__, {"x" : 42})
205+
# del cm.x
206+
# self.assertTrue(not hasattr(cm, "x"))
207+
208+
def test_supers(self):
209+
# Testing super...
210+
211+
class A(object):
212+
def meth(self, a):
213+
return "A(%r)" % a
214+
215+
self.assertEqual(A().meth(1), "A(1)")
216+
217+
class B(A):
218+
def __init__(self):
219+
self.__super = super(B, self)
220+
def meth(self, a):
221+
return "B(%r)" % a + self.__super.meth(a)
222+
223+
self.assertEqual(B().meth(2), "B(2)A(2)")
224+
225+
class C(A):
226+
def meth(self, a):
227+
return "C(%r)" % a + self.__super.meth(a)
228+
C._C__super = super(C)
229+
230+
self.assertEqual(C().meth(3), "C(3)A(3)")
231+
232+
class D(C, B):
233+
def meth(self, a):
234+
return "D(%r)" % a + super(D, self).meth(a)
235+
236+
self.assertEqual(D().meth(4), "D(4)C(4)B(4)A(4)")
237+
238+
# # Test for subclassing super
239+
240+
# class mysuper(super):
241+
# def __init__(self, *args):
242+
# return super(mysuper, self).__init__(*args)
243+
244+
# class E(D):
245+
# def meth(self, a):
246+
# return "E(%r)" % a + mysuper(E, self).meth(a)
247+
248+
# self.assertEqual(E().meth(5), "E(5)D(5)C(5)B(5)A(5)")
249+
250+
# class F(E):
251+
# def meth(self, a):
252+
# s = self.__super # == mysuper(F, self)
253+
# return "F(%r)[%s]" % (a, s.__class__.__name__) + s.meth(a)
254+
# F._F__super = mysuper(F)
255+
256+
# self.assertEqual(F().meth(6), "F(6)[mysuper]E(6)D(6)C(6)B(6)A(6)")
257+
258+
# Make sure certain errors are raised
259+
260+
try:
261+
super(D, 42)
262+
except TypeError:
263+
pass
264+
else:
265+
self.fail("shouldn't allow super(D, 42)")
266+
267+
try:
268+
super(D, C())
269+
except TypeError:
270+
pass
271+
else:
272+
self.fail("shouldn't allow super(D, C())")
273+
274+
try:
275+
super(D).__get__(12)
276+
except TypeError:
277+
pass
278+
else:
279+
self.fail("shouldn't allow super(D).__get__(12)")
280+
281+
try:
282+
super(D).__get__(C())
283+
except TypeError:
284+
pass
285+
else:
286+
self.fail("shouldn't allow super(D).__get__(C())")
287+
288+
# Make sure data descriptors can be overridden and accessed via super
289+
# (new feature in Python 2.3)
290+
291+
class DDbase(object):
292+
def getx(self): return 42
293+
x = property(getx)
294+
295+
class DDsub(DDbase):
296+
def getx(self): return "hello"
297+
x = property(getx)
298+
299+
dd = DDsub()
300+
self.assertEqual(dd.x, "hello")
301+
self.assertEqual(super(DDsub, dd).x, 42)
302+
303+
# Ensure that super() lookup of descriptor from classmethod
304+
# works (SF ID# 743627)
305+
306+
class Base(object):
307+
aProp = property(lambda self: "foo")
308+
309+
class Sub(Base):
310+
@classmethod
311+
def test(klass):
312+
return super(Sub,klass).aProp
313+
314+
self.assertEqual(Sub.test(), Base.aProp)
315+
316+
# Verify that super() doesn't allow keyword args
317+
try:
318+
super(Base, kw=1)
319+
except TypeError:
320+
pass
321+
else:
322+
self.assertEqual("super shouldn't accept keyword args")
323+
324+
150325
if __name__ == "__main__":
151326
unittest.main()

0 commit comments

Comments
 (0)