Skip to content

Commit 751c9ed

Browse files
authored
bpo-46891: Fix creating a new instance of a module subclass with slots (GH-31643)
1 parent 3c4abfa commit 751c9ed

File tree

3 files changed

+24
-1
lines changed

3 files changed

+24
-1
lines changed

Lib/test/test_module.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,25 @@ def test_repeated_attribute_pops(self):
346346

347347
# frozen and namespace module reprs are tested in importlib.
348348

349+
def test_subclass_with_slots(self):
350+
# In 3.11alpha this crashed, as the slots weren't NULLed.
351+
352+
class ModuleWithSlots(ModuleType):
353+
__slots__ = ("a", "b")
354+
355+
def __init__(self, name):
356+
super().__init__(name)
357+
358+
m = ModuleWithSlots("name")
359+
with self.assertRaises(AttributeError):
360+
m.a
361+
with self.assertRaises(AttributeError):
362+
m.b
363+
m.a, m.b = 1, 2
364+
self.assertEqual(m.a, 1)
365+
self.assertEqual(m.b, 2)
366+
367+
349368

350369
if __name__ == '__main__':
351370
unittest.main()
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix bug introduced during 3.11alpha where subclasses of ``types.ModuleType``
2+
with ``__slots__`` were not initialized correctly, resulting in an
3+
interpreter crash.

Objects/moduleobject.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "Python.h"
55
#include "pycore_call.h" // _PyObject_CallNoArgs()
66
#include "pycore_interp.h" // PyInterpreterState.importlib
7+
#include "pycore_object.h" // _PyType_AllocNoTrack
78
#include "pycore_pystate.h" // _PyInterpreterState_GET()
89
#include "pycore_moduleobject.h" // _PyModule_GetDef()
910
#include "structmember.h" // PyMemberDef
@@ -80,7 +81,7 @@ static PyModuleObject *
8081
new_module_notrack(PyTypeObject *mt)
8182
{
8283
PyModuleObject *m;
83-
m = PyObject_GC_New(PyModuleObject, mt);
84+
m = (PyModuleObject *)_PyType_AllocNoTrack(mt, 0);
8485
if (m == NULL)
8586
return NULL;
8687
m->md_def = NULL;

0 commit comments

Comments
 (0)