diff options
-rw-r--r-- | Lib/test/test_module.py | 19 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Core and Builtins/2022-03-02-15-04-08.bpo-46891.aIAgTD.rst | 3 | ||||
-rw-r--r-- | Objects/moduleobject.c | 3 |
3 files changed, 24 insertions, 1 deletions
diff --git a/Lib/test/test_module.py b/Lib/test/test_module.py index 619348e0e40..f72177dda37 100644 --- a/Lib/test/test_module.py +++ b/Lib/test/test_module.py @@ -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 index 00000000000..6834b08a885 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-02-15-04-08.bpo-46891.aIAgTD.rst @@ -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. diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index 72ed9bb82f9..738b262288b 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -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; |