summaryrefslogtreecommitdiff
path: root/Lib/test/test_super.py
diff options
context:
space:
mode:
authorNick Coghlan <ncoghlan@gmail.com>2016-09-11 14:45:49 +1000
committerNick Coghlan <ncoghlan@gmail.com>2016-09-11 14:45:49 +1000
commit0780d6cb0e6e406d0030dee40156a6dd00066147 (patch)
tree0d2f017d3c398d69513e81b31c2a489252f6acc6 /Lib/test/test_super.py
parent84f77c2f0f78aca1337ab3ddc00dff10fedfcad1 (diff)
downloadcpython-0780d6cb0e6e406d0030dee40156a6dd00066147.tar.gz
Issue #23722: Initialize __class__ from type.__new__()
The __class__ cell used by zero-argument super() is now initialized from type.__new__ rather than __build_class__, so class methods relying on that will now work correctly when called from metaclass methods during class creation. Patch by Martin Teichmann.
Diffstat (limited to 'Lib/test/test_super.py')
-rw-r--r--Lib/test/test_super.py81
1 files changed, 81 insertions, 0 deletions
diff --git a/Lib/test/test_super.py b/Lib/test/test_super.py
index b84863fe53..a7ceded0b8 100644
--- a/Lib/test/test_super.py
+++ b/Lib/test/test_super.py
@@ -143,6 +143,87 @@ class TestSuper(unittest.TestCase):
return __class__
self.assertIs(X.f(), X)
+ def test___class___new(self):
+ test_class = None
+
+ class Meta(type):
+ def __new__(cls, name, bases, namespace):
+ nonlocal test_class
+ self = super().__new__(cls, name, bases, namespace)
+ test_class = self.f()
+ return self
+
+ class A(metaclass=Meta):
+ @staticmethod
+ def f():
+ return __class__
+
+ self.assertIs(test_class, A)
+
+ def test___class___delayed(self):
+ test_namespace = None
+
+ class Meta(type):
+ def __new__(cls, name, bases, namespace):
+ nonlocal test_namespace
+ test_namespace = namespace
+ return None
+
+ class A(metaclass=Meta):
+ @staticmethod
+ def f():
+ return __class__
+
+ self.assertIs(A, None)
+
+ B = type("B", (), test_namespace)
+ self.assertIs(B.f(), B)
+
+ def test___class___mro(self):
+ test_class = None
+
+ class Meta(type):
+ def mro(self):
+ # self.f() doesn't work yet...
+ self.__dict__["f"]()
+ return super().mro()
+
+ class A(metaclass=Meta):
+ def f():
+ nonlocal test_class
+ test_class = __class__
+
+ self.assertIs(test_class, A)
+
+ def test___classcell___deleted(self):
+ class Meta(type):
+ def __new__(cls, name, bases, namespace):
+ del namespace['__classcell__']
+ return super().__new__(cls, name, bases, namespace)
+
+ class A(metaclass=Meta):
+ @staticmethod
+ def f():
+ __class__
+
+ with self.assertRaises(NameError):
+ A.f()
+
+ def test___classcell___reset(self):
+ class Meta(type):
+ def __new__(cls, name, bases, namespace):
+ namespace['__classcell__'] = 0
+ return super().__new__(cls, name, bases, namespace)
+
+ class A(metaclass=Meta):
+ @staticmethod
+ def f():
+ __class__
+
+ with self.assertRaises(NameError):
+ A.f()
+ self.assertEqual(A.__classcell__, 0)
+
def test_obscure_super_errors(self):
def f():
super()