mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 07:31:38 +00:00 
			
		
		
		
	This prevents the assignment of __class__ in the class body from breaking super. (Although a determined person could do locals()["@__class__"] = 4)
		
			
				
	
	
		
			100 lines
		
	
	
	
		
			2.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			100 lines
		
	
	
	
		
			2.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
"""Unit tests for new super() implementation."""
 | 
						|
 | 
						|
import sys
 | 
						|
import unittest
 | 
						|
from test import support
 | 
						|
 | 
						|
 | 
						|
class A:
 | 
						|
    def f(self):
 | 
						|
        return 'A'
 | 
						|
    @classmethod
 | 
						|
    def cm(cls):
 | 
						|
        return (cls, 'A')
 | 
						|
 | 
						|
class B(A):
 | 
						|
    def f(self):
 | 
						|
        return super().f() + 'B'
 | 
						|
    @classmethod
 | 
						|
    def cm(cls):
 | 
						|
        return (cls, super().cm(), 'B')
 | 
						|
 | 
						|
class C(A):
 | 
						|
    def f(self):
 | 
						|
        return super().f() + 'C'
 | 
						|
    @classmethod
 | 
						|
    def cm(cls):
 | 
						|
        return (cls, super().cm(), 'C')
 | 
						|
 | 
						|
class D(C, B):
 | 
						|
    def f(self):
 | 
						|
        return super().f() + 'D'
 | 
						|
    def cm(cls):
 | 
						|
        return (cls, super().cm(), 'D')
 | 
						|
 | 
						|
class E(D):
 | 
						|
    pass
 | 
						|
 | 
						|
class F(E):
 | 
						|
    f = E.f
 | 
						|
 | 
						|
class G(A):
 | 
						|
    pass
 | 
						|
 | 
						|
 | 
						|
class TestSuper(unittest.TestCase):
 | 
						|
 | 
						|
    def test_basics_working(self):
 | 
						|
        self.assertEqual(D().f(), 'ABCD')
 | 
						|
 | 
						|
    def test_class_getattr_working(self):
 | 
						|
        self.assertEqual(D.f(D()), 'ABCD')
 | 
						|
 | 
						|
    def test_subclass_no_override_working(self):
 | 
						|
        self.assertEqual(E().f(), 'ABCD')
 | 
						|
        self.assertEqual(E.f(E()), 'ABCD')
 | 
						|
 | 
						|
    def test_unbound_method_transfer_working(self):
 | 
						|
        self.assertEqual(F().f(), 'ABCD')
 | 
						|
        self.assertEqual(F.f(F()), 'ABCD')
 | 
						|
 | 
						|
    def test_class_methods_still_working(self):
 | 
						|
        self.assertEqual(A.cm(), (A, 'A'))
 | 
						|
        self.assertEqual(A().cm(), (A, 'A'))
 | 
						|
        self.assertEqual(G.cm(), (G, 'A'))
 | 
						|
        self.assertEqual(G().cm(), (G, 'A'))
 | 
						|
 | 
						|
    def test_super_in_class_methods_working(self):
 | 
						|
        d = D()
 | 
						|
        self.assertEqual(d.cm(), (d, (D, (D, (D, 'A'), 'B'), 'C'), 'D'))
 | 
						|
        e = E()
 | 
						|
        self.assertEqual(e.cm(), (e, (E, (E, (E, 'A'), 'B'), 'C'), 'D'))
 | 
						|
 | 
						|
    def test_super_with_closure(self):
 | 
						|
        # Issue4360: super() did not work in a function that
 | 
						|
        # contains a closure
 | 
						|
        class E(A):
 | 
						|
            def f(self):
 | 
						|
                def nested():
 | 
						|
                    self
 | 
						|
                return super().f() + 'E'
 | 
						|
 | 
						|
        self.assertEqual(E().f(), 'AE')
 | 
						|
 | 
						|
    def test___class___set(self):
 | 
						|
        # See issue #12370
 | 
						|
        class X(A):
 | 
						|
            def f(self):
 | 
						|
                return super().f()
 | 
						|
            __class__ = 413
 | 
						|
        x = X()
 | 
						|
        self.assertEqual(x.f(), 'A')
 | 
						|
        self.assertEqual(x.__class__, 413)
 | 
						|
 | 
						|
 | 
						|
def test_main():
 | 
						|
    support.run_unittest(TestSuper)
 | 
						|
 | 
						|
 | 
						|
if __name__ == "__main__":
 | 
						|
    unittest.main()
 |