summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_super.py
diff options
context:
space:
mode:
authorNick Coghlan <ncoghlan@gmail.com>2016-09-11 04:45:49 (GMT)
committerNick Coghlan <ncoghlan@gmail.com>2016-09-11 04:45:49 (GMT)
commit944368e1cc90a0bebaaf1a0a6f4346a81d8f46ad (patch)
treeea2c59fec386dfbe32c0f53ba8a85f75860e554d /Lib/test/test_super.py
parentfc3f7d56773b3816eb0e8f4151239a0983aedb2c (diff)
downloadcpython-944368e1cc90a0bebaaf1a0a6f4346a81d8f46ad.zip
cpython-944368e1cc90a0bebaaf1a0a6f4346a81d8f46ad.tar.gz
cpython-944368e1cc90a0bebaaf1a0a6f4346a81d8f46ad.tar.bz2
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 b84863f..a7ceded 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()