]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-46891: Fix creating a new instance of a module subclass with slots (GH-31643)
authorMark Shannon <mark@hotpy.org>
Thu, 3 Mar 2022 10:38:27 +0000 (10:38 +0000)
committerGitHub <noreply@github.com>
Thu, 3 Mar 2022 10:38:27 +0000 (10:38 +0000)
Lib/test/test_module.py
Misc/NEWS.d/next/Core and Builtins/2022-03-02-15-04-08.bpo-46891.aIAgTD.rst [new file with mode: 0644]
Objects/moduleobject.c

index 619348e0e40c03b92bb4948226247d3a95b20d74..f72177dda3702aa0aa6df33982088a3eb433c9ba 100644 (file)
@@ -346,6 +346,25 @@ a = A(destroyed)"""
 
     # frozen and namespace module reprs are tested in importlib.
 
+    def test_subclass_with_slots(self):
+        # In 3.11alpha this crashed, as the slots weren't NULLed.
+
+        class ModuleWithSlots(ModuleType):
+            __slots__ = ("a", "b")
+
+            def __init__(self, name):
+                super().__init__(name)
+
+        m = ModuleWithSlots("name")
+        with self.assertRaises(AttributeError):
+            m.a
+        with self.assertRaises(AttributeError):
+            m.b
+        m.a, m.b = 1, 2
+        self.assertEqual(m.a, 1)
+        self.assertEqual(m.b, 2)
+
+
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-02-15-04-08.bpo-46891.aIAgTD.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-02-15-04-08.bpo-46891.aIAgTD.rst
new file mode 100644 (file)
index 0000000..6834b08
--- /dev/null
@@ -0,0 +1,3 @@
+Fix bug introduced during 3.11alpha where subclasses of ``types.ModuleType``
+with ``__slots__`` were not initialized correctly, resulting in an
+interpreter crash.
index 72ed9bb82f9708810c78aa41ba10156f0bb46ef2..738b262288bcd4e468de28a1b597f9ad93152437 100644 (file)
@@ -4,6 +4,7 @@
 #include "Python.h"
 #include "pycore_call.h"          // _PyObject_CallNoArgs()
 #include "pycore_interp.h"        // PyInterpreterState.importlib
+#include "pycore_object.h"        // _PyType_AllocNoTrack
 #include "pycore_pystate.h"       // _PyInterpreterState_GET()
 #include "pycore_moduleobject.h"  // _PyModule_GetDef()
 #include "structmember.h"         // PyMemberDef
@@ -80,7 +81,7 @@ static PyModuleObject *
 new_module_notrack(PyTypeObject *mt)
 {
     PyModuleObject *m;
-    m = PyObject_GC_New(PyModuleObject, mt);
+    m = (PyModuleObject *)_PyType_AllocNoTrack(mt, 0);
     if (m == NULL)
         return NULL;
     m->md_def = NULL;