From d1ceef45f4d6ac8e283fa2cae0d9c31d2850cb81 Mon Sep 17 00:00:00 2001 From: AN Long Date: Sun, 9 Apr 2023 22:31:37 +0800 Subject: [PATCH 1/6] Using multi-phase initialization for _ctypes module --- Modules/_ctypes/_ctypes.c | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 6f92ca08dd537b..8781dc61d99b15 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -5601,15 +5601,6 @@ wstring_at(const wchar_t *ptr, int size) } -static struct PyModuleDef _ctypesmodule = { - PyModuleDef_HEAD_INIT, - .m_name = "_ctypes", - .m_doc = _ctypes__doc__, - .m_size = -1, - .m_methods = _ctypes_module_methods, -}; - - static int _ctypes_add_types(PyObject *mod) { @@ -5783,19 +5774,26 @@ _ctypes_mod_exec(PyObject *mod) } +static PyModuleDef_Slot _ctypes_module_slots[] = { + {Py_mod_exec, _ctypes_mod_exec}, + {0, NULL} +}; + + +static struct PyModuleDef _ctypesmodule = { + PyModuleDef_HEAD_INIT, + .m_name = "_ctypes", + .m_doc = _ctypes__doc__, + .m_size = 0, + .m_methods = _ctypes_module_methods, + .m_slots = _ctypes_module_slots, +}; + + PyMODINIT_FUNC PyInit__ctypes(void) { - PyObject *mod = PyModule_Create(&_ctypesmodule); - if (!mod) { - return NULL; - } - - if (_ctypes_mod_exec(mod) < 0) { - Py_DECREF(mod); - return NULL; - } - return mod; + return PyModuleDef_Init(&_ctypesmodule); } /* From 3a953b83ed898db9ed270878420d0692ef60e42f Mon Sep 17 00:00:00 2001 From: AN Long Date: Wed, 19 Apr 2023 00:05:25 +0800 Subject: [PATCH 2/6] port _ctypes.Union to heap type --- Modules/_ctypes/_ctypes.c | 53 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 8781dc61d99b15..3927ee6c1dabef 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -144,6 +144,10 @@ PyObject *ComError; // Borrowed reference to: &PyComError_Type /****************************************************************/ +typedef struct { + PyTypeObject *Union_Type; +} _ctypes_state; + typedef struct { PyObject_HEAD PyObject *key; @@ -4485,6 +4489,21 @@ static PyTypeObject Union_Type = { 0, /* tp_free */ }; +static PyType_Slot union_type_slots[] = { + {Py_bf_getbuffer, PyCData_NewGetBuffer}, + {Py_tp_traverse, PyCData_traverse}, + {Py_tp_clear, PyCData_clear}, + {Py_tp_init, Struct_init}, + {Py_tp_new, GenericPyCData_new}, + {0, NULL}, +}; + +static PyType_Spec union_type_spec = { + .name = "_ctypes.Union", + .basicsize = sizeof(CDataObject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + .slots = &union_type_slots, +}; /******************************************************************/ /* @@ -5626,6 +5645,9 @@ _ctypes_add_types(PyObject *mod) } \ } while (0) + _ctypes_state *st = PyModule_GetState(mod); + assert(st); + /* Note: ob_type is the metatype (the 'type'), defaults to PyType_Type, tp_base is the base type, defaults to 'object' aka PyBaseObject_Type. @@ -5653,12 +5675,21 @@ _ctypes_add_types(PyObject *mod) */ MOD_ADD_TYPE(&Struct_Type, &PyCStructType_Type, &PyCData_Type); - MOD_ADD_TYPE(&Union_Type, &UnionType_Type, &PyCData_Type); + // MOD_ADD_TYPE(&Union_Type, &UnionType_Type, &PyCData_Type); MOD_ADD_TYPE(&PyCPointer_Type, &PyCPointerType_Type, &PyCData_Type); MOD_ADD_TYPE(&PyCArray_Type, &PyCArrayType_Type, &PyCData_Type); MOD_ADD_TYPE(&Simple_Type, &PyCSimpleType_Type, &PyCData_Type); MOD_ADD_TYPE(&PyCFuncPtr_Type, &PyCFuncPtrType_Type, &PyCData_Type); + st->Union_Type = (PyTypeObject *)PyType_FromModuleAndSpec(mod, &union_type_spec, &PyCData_Type); + if (st->Union_Type == NULL) { + return -1; + } + Py_SET_TYPE(st->Union_Type, &UnionType_Type); + if (PyModule_AddType(mod, st->Union_Type) < 0) { + return -1; + } + /************************************************* * * Simple classes @@ -5780,13 +5811,31 @@ static PyModuleDef_Slot _ctypes_module_slots[] = { }; +static int +_ctypes_traverse(PyObject *mod, visitproc visit, void *arg) +{ + _ctypes_state *st = _PyModule_GetState(mod); + Py_VISIT(st->Union_Type); + return 0; +} + +static int +_ctypes_clear(PyObject *mod) +{ + _ctypes_state *st = _PyModule_GetState(mod); + Py_CLEAR(st->Union_Type); + return 0; +} + static struct PyModuleDef _ctypesmodule = { PyModuleDef_HEAD_INIT, .m_name = "_ctypes", .m_doc = _ctypes__doc__, - .m_size = 0, + .m_size = sizeof(_ctypes_state), .m_methods = _ctypes_module_methods, .m_slots = _ctypes_module_slots, + .m_traverse = _ctypes_traverse, + .m_clear = _ctypes_clear, }; From 7e8b115a6e86d902a1734467ddb4675523e403f0 Mon Sep 17 00:00:00 2001 From: AN Long Date: Wed, 19 Apr 2023 22:23:48 +0800 Subject: [PATCH 3/6] fix compiler warnings --- Modules/_ctypes/_ctypes.c | 48 ++++----------------------------------- 1 file changed, 4 insertions(+), 44 deletions(-) diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 3927ee6c1dabef..619c2ce618c67e 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -4447,48 +4447,6 @@ static PyTypeObject Struct_Type = { 0, /* tp_free */ }; -static PyTypeObject Union_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.Union", - sizeof(CDataObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - &PyCData_as_buffer, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - PyDoc_STR("Union base class"), /* tp_doc */ - (traverseproc)PyCData_traverse, /* tp_traverse */ - (inquiry)PyCData_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - Struct_init, /* tp_init */ - 0, /* tp_alloc */ - GenericPyCData_new, /* tp_new */ - 0, /* tp_free */ -}; - static PyType_Slot union_type_slots[] = { {Py_bf_getbuffer, PyCData_NewGetBuffer}, {Py_tp_traverse, PyCData_traverse}, @@ -4502,7 +4460,7 @@ static PyType_Spec union_type_spec = { .name = "_ctypes.Union", .basicsize = sizeof(CDataObject), .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, - .slots = &union_type_slots, + .slots = union_type_slots, }; /******************************************************************/ @@ -5681,7 +5639,9 @@ _ctypes_add_types(PyObject *mod) MOD_ADD_TYPE(&Simple_Type, &PyCSimpleType_Type, &PyCData_Type); MOD_ADD_TYPE(&PyCFuncPtr_Type, &PyCFuncPtrType_Type, &PyCData_Type); - st->Union_Type = (PyTypeObject *)PyType_FromModuleAndSpec(mod, &union_type_spec, &PyCData_Type); + st->Union_Type = (PyTypeObject *) + PyType_FromModuleAndSpec(mod, &union_type_spec, + (PyObject *)&PyCData_Type); if (st->Union_Type == NULL) { return -1; } From d70ba69bd8c81907fe714344cb0559e282ba60d9 Mon Sep 17 00:00:00 2001 From: AN Long Date: Sat, 22 Apr 2023 01:08:22 +0800 Subject: [PATCH 4/6] port _ctypes.UnionType to heap type --- Modules/_ctypes/_ctypes.c | 69 +++++++++++++++------------------------ 1 file changed, 26 insertions(+), 43 deletions(-) diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 619c2ce618c67e..985c81a92065c4 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -146,6 +146,7 @@ PyObject *ComError; // Borrowed reference to: &PyComError_Type typedef struct { PyTypeObject *Union_Type; + PyTypeObject *UnionType_Type; } _ctypes_state; typedef struct { @@ -964,48 +965,24 @@ PyTypeObject PyCStructType_Type = { 0, /* tp_free */ }; -static PyTypeObject UnionType_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.UnionType", /* tp_name */ - 0, /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - &CDataType_as_sequence, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - UnionType_setattro, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - PyDoc_STR("metatype for the CData Objects"), /* tp_doc */ - (traverseproc)CDataType_traverse, /* tp_traverse */ - (inquiry)CDataType_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - CDataType_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - UnionType_new, /* tp_new */ - 0, /* tp_free */ +static PyType_Slot union_type_type_slots[] = { + {Py_sq_repeat, CDataType_repeat}, + {Py_tp_setattro, UnionType_setattro}, + {Py_tp_doc, PyDoc_STR("metatype for the CData Objects")}, + {Py_tp_traverse, CDataType_traverse}, + {Py_tp_clear, CDataType_clear}, + {Py_tp_methods, CDataType_methods}, + {Py_tp_new, UnionType_new}, + {Py_tp_base, &PyType_Type}, + {0, NULL}, }; +static PyType_Spec union_type_type_spec = { + .name = "_ctypes.UnionType", + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_TYPE_SUBCLASS | Py_TPFLAGS_IMMUTABLETYPE), + .slots = union_type_type_slots, +}; /******************************************************************/ @@ -5621,19 +5598,24 @@ _ctypes_add_types(PyObject *mod) * Metaclasses */ TYPE_READY_BASE(&PyCStructType_Type, &PyType_Type); - TYPE_READY_BASE(&UnionType_Type, &PyType_Type); TYPE_READY_BASE(&PyCPointerType_Type, &PyType_Type); TYPE_READY_BASE(&PyCArrayType_Type, &PyType_Type); TYPE_READY_BASE(&PyCSimpleType_Type, &PyType_Type); TYPE_READY_BASE(&PyCFuncPtrType_Type, &PyType_Type); + st->UnionType_Type = (PyTypeObject *) + PyType_FromModuleAndSpec(mod, &union_type_type_spec, + NULL); + if (st->UnionType_Type == NULL) { + return -1; + } + /************************************************* * * Classes using a custom metaclass */ MOD_ADD_TYPE(&Struct_Type, &PyCStructType_Type, &PyCData_Type); - // MOD_ADD_TYPE(&Union_Type, &UnionType_Type, &PyCData_Type); MOD_ADD_TYPE(&PyCPointer_Type, &PyCPointerType_Type, &PyCData_Type); MOD_ADD_TYPE(&PyCArray_Type, &PyCArrayType_Type, &PyCData_Type); MOD_ADD_TYPE(&Simple_Type, &PyCSimpleType_Type, &PyCData_Type); @@ -5645,7 +5627,8 @@ _ctypes_add_types(PyObject *mod) if (st->Union_Type == NULL) { return -1; } - Py_SET_TYPE(st->Union_Type, &UnionType_Type); + Py_SET_TYPE(st->Union_Type, st->UnionType_Type); + if (PyModule_AddType(mod, st->Union_Type) < 0) { return -1; } From d8c5f6c96199e27eeec2de28c7cabd21118d957e Mon Sep 17 00:00:00 2001 From: AN Long Date: Sat, 22 Apr 2023 23:05:53 +0800 Subject: [PATCH 5/6] fix build on windows --- Modules/_ctypes/_ctypes.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 985c81a92065c4..32e691819f9b25 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -966,6 +966,7 @@ PyTypeObject PyCStructType_Type = { }; static PyType_Slot union_type_type_slots[] = { + {Py_tp_base, NULL}, // filled out in module exec function {Py_sq_repeat, CDataType_repeat}, {Py_tp_setattro, UnionType_setattro}, {Py_tp_doc, PyDoc_STR("metatype for the CData Objects")}, @@ -973,7 +974,6 @@ static PyType_Slot union_type_type_slots[] = { {Py_tp_clear, CDataType_clear}, {Py_tp_methods, CDataType_methods}, {Py_tp_new, UnionType_new}, - {Py_tp_base, &PyType_Type}, {0, NULL}, }; @@ -4426,6 +4426,7 @@ static PyTypeObject Struct_Type = { static PyType_Slot union_type_slots[] = { {Py_bf_getbuffer, PyCData_NewGetBuffer}, + {Py_tp_doc, PyDoc_STR("Union base class")}, {Py_tp_traverse, PyCData_traverse}, {Py_tp_clear, PyCData_clear}, {Py_tp_init, Struct_init}, @@ -4436,7 +4437,8 @@ static PyType_Slot union_type_slots[] = { static PyType_Spec union_type_spec = { .name = "_ctypes.Union", .basicsize = sizeof(CDataObject), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), .slots = union_type_slots, }; @@ -5603,6 +5605,7 @@ _ctypes_add_types(PyObject *mod) TYPE_READY_BASE(&PyCSimpleType_Type, &PyType_Type); TYPE_READY_BASE(&PyCFuncPtrType_Type, &PyType_Type); + union_type_type_slots[0].pfunc = &PyType_Type; st->UnionType_Type = (PyTypeObject *) PyType_FromModuleAndSpec(mod, &union_type_type_spec, NULL); @@ -5759,6 +5762,7 @@ _ctypes_traverse(PyObject *mod, visitproc visit, void *arg) { _ctypes_state *st = _PyModule_GetState(mod); Py_VISIT(st->Union_Type); + Py_VISIT(st->UnionType_Type); return 0; } @@ -5767,6 +5771,7 @@ _ctypes_clear(PyObject *mod) { _ctypes_state *st = _PyModule_GetState(mod); Py_CLEAR(st->Union_Type); + Py_CLEAR(st->UnionType_Type); return 0; } From 978461e7e07429167978c980334d757acc1e4016 Mon Sep 17 00:00:00 2001 From: AN Long Date: Sun, 23 Apr 2023 00:51:02 +0800 Subject: [PATCH 6/6] port _ctypes.Structure and it's metaclass to heap type --- Modules/_ctypes/_ctypes.c | 141 ++++++++++++++++---------------------- 1 file changed, 58 insertions(+), 83 deletions(-) diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 32e691819f9b25..b4345b93f5382f 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -145,6 +145,8 @@ PyObject *ComError; // Borrowed reference to: &PyComError_Type /****************************************************************/ typedef struct { + PyTypeObject *Struct_Type; + PyTypeObject *PyCStructType_Type; PyTypeObject *Union_Type; PyTypeObject *UnionType_Type; } _ctypes_state; @@ -923,46 +925,23 @@ UnionType_setattro(PyObject *self, PyObject *key, PyObject *value) } -PyTypeObject PyCStructType_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.PyCStructType", /* tp_name */ - 0, /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - &CDataType_as_sequence, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - PyCStructType_setattro, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - PyDoc_STR("metatype for the CData Objects"), /* tp_doc */ - (traverseproc)CDataType_traverse, /* tp_traverse */ - (inquiry)CDataType_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - CDataType_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - PyCStructType_new, /* tp_new */ - 0, /* tp_free */ +static PyType_Slot pycstruct_type_type_slots[] = { + {Py_tp_base, NULL}, // filled out in module exec function + {Py_sq_repeat, CDataType_repeat}, + {Py_tp_setattro, PyCStructType_setattro}, + {Py_tp_doc, PyDoc_STR("metatype for the CData Objects")}, + {Py_tp_traverse, CDataType_traverse}, + {Py_tp_clear, CDataType_clear}, + {Py_tp_methods, CDataType_methods}, + {Py_tp_new, PyCStructType_new}, + {0, NULL}, +}; + +PyType_Spec pycstruct_type_type_spec = { + .name = "_ctypes.PyCStructType", + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = pycstruct_type_type_slots, }; static PyType_Slot union_type_type_slots[] = { @@ -4382,46 +4361,21 @@ Struct_init(PyObject *self, PyObject *args, PyObject *kwds) return 0; } -static PyTypeObject Struct_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.Structure", - sizeof(CDataObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - &PyCData_as_buffer, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - PyDoc_STR("Structure base class"), /* tp_doc */ - (traverseproc)PyCData_traverse, /* tp_traverse */ - (inquiry)PyCData_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - Struct_init, /* tp_init */ - 0, /* tp_alloc */ - GenericPyCData_new, /* tp_new */ - 0, /* tp_free */ +static PyType_Slot struct_type_slots[] = { + {Py_bf_getbuffer, PyCData_NewGetBuffer}, + {Py_tp_traverse, PyCData_traverse}, + {Py_tp_clear, PyCData_clear}, + {Py_tp_init, Struct_init}, + {Py_tp_new, GenericPyCData_new}, + {0, NULL}, +}; + +static PyType_Spec struct_type_spec = { + .name = "_ctypes.Structure", + .basicsize = sizeof(CDataObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = struct_type_slots, }; static PyType_Slot union_type_slots[] = { @@ -5599,7 +5553,6 @@ _ctypes_add_types(PyObject *mod) * * Metaclasses */ - TYPE_READY_BASE(&PyCStructType_Type, &PyType_Type); TYPE_READY_BASE(&PyCPointerType_Type, &PyType_Type); TYPE_READY_BASE(&PyCArrayType_Type, &PyType_Type); TYPE_READY_BASE(&PyCSimpleType_Type, &PyType_Type); @@ -5613,17 +5566,36 @@ _ctypes_add_types(PyObject *mod) return -1; } + pycstruct_type_type_slots[0].pfunc = &PyType_Type; + st->PyCStructType_Type = (PyTypeObject *) + PyType_FromModuleAndSpec(mod, + &pycstruct_type_type_spec, + NULL); + if (st->PyCStructType_Type == NULL) { + return -1; + } + /************************************************* * * Classes using a custom metaclass */ - MOD_ADD_TYPE(&Struct_Type, &PyCStructType_Type, &PyCData_Type); MOD_ADD_TYPE(&PyCPointer_Type, &PyCPointerType_Type, &PyCData_Type); MOD_ADD_TYPE(&PyCArray_Type, &PyCArrayType_Type, &PyCData_Type); MOD_ADD_TYPE(&Simple_Type, &PyCSimpleType_Type, &PyCData_Type); MOD_ADD_TYPE(&PyCFuncPtr_Type, &PyCFuncPtrType_Type, &PyCData_Type); + st->Struct_Type = (PyTypeObject *) + PyType_FromModuleAndSpec(mod, &struct_type_spec, + (PyObject *)&PyCData_Type); + if (st->Struct_Type == NULL) { + return -1; + } + Py_SET_TYPE(st->Struct_Type, st->PyCStructType_Type); + if (PyModule_AddType(mod, st->Struct_Type) < 0) { + return -1; + } + st->Union_Type = (PyTypeObject *) PyType_FromModuleAndSpec(mod, &union_type_spec, (PyObject *)&PyCData_Type); @@ -5631,7 +5603,6 @@ _ctypes_add_types(PyObject *mod) return -1; } Py_SET_TYPE(st->Union_Type, st->UnionType_Type); - if (PyModule_AddType(mod, st->Union_Type) < 0) { return -1; } @@ -5761,6 +5732,8 @@ static int _ctypes_traverse(PyObject *mod, visitproc visit, void *arg) { _ctypes_state *st = _PyModule_GetState(mod); + Py_VISIT(st->PyCStructType_Type); + Py_VISIT(st->Struct_Type); Py_VISIT(st->Union_Type); Py_VISIT(st->UnionType_Type); return 0; @@ -5770,6 +5743,8 @@ static int _ctypes_clear(PyObject *mod) { _ctypes_state *st = _PyModule_GetState(mod); + Py_CLEAR(st->PyCStructType_Type); + Py_CLEAR(st->Struct_Type); Py_CLEAR(st->Union_Type); Py_CLEAR(st->UnionType_Type); return 0;