[Python-checkins] gh-103092: Port _ctypes.COMError to heap type (#104020)
erlend-aasland
webhook-mailer at python.org
Thu May 4 09:03:32 EDT 2023
https://github.com/python/cpython/commit/4f524da4843fb71b3ba43d89cd0265e4ecb29798
commit: 4f524da4843fb71b3ba43d89cd0265e4ecb29798
branch: main
author: Erlend E. Aasland <erlend.aasland at protonmail.com>
committer: erlend-aasland <erlend.aasland at protonmail.com>
date: 2023-05-04T13:03:24Z
summary:
gh-103092: Port _ctypes.COMError to heap type (#104020)
files:
M Modules/_ctypes/_ctypes.c
M Modules/_ctypes/callproc.c
M Modules/_ctypes/ctypes.h
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
index c7ed6bd2229c..f6cda45eaeac 100644
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -139,10 +139,6 @@ static PyTypeObject Simple_Type;
strong reference to _ctypes._unpickle() function */
static PyObject *_unpickle;
-#ifdef MS_WIN32
-PyObject *ComError; // Borrowed reference to: &PyComError_Type
-#endif
-
/****************************************************************/
@@ -5480,46 +5476,38 @@ comerror_init(PyObject *self, PyObject *args, PyObject *kwds)
return 0;
}
-static PyTypeObject PyComError_Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "_ctypes.COMError", /* tp_name */
- sizeof(PyBaseExceptionObject), /* 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 */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- PyDoc_STR(comerror_doc), /* tp_doc */
- 0, /* tp_traverse */
- 0, /* 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 */
- (initproc)comerror_init, /* tp_init */
- 0, /* tp_alloc */
- 0, /* tp_new */
+static int
+comerror_traverse(PyObject *self, visitproc visit, void *arg)
+{
+ Py_VISIT(Py_TYPE(self));
+ return 0;
+}
+
+static void
+comerror_dealloc(PyObject *self)
+{
+ PyTypeObject *tp = Py_TYPE(self);
+ PyObject_GC_UnTrack(self);
+ tp->tp_free(self);
+ Py_DECREF(tp);
+}
+
+static PyType_Slot comerror_slots[] = {
+ {Py_tp_doc, (void *)PyDoc_STR(comerror_doc)},
+ {Py_tp_init, comerror_init},
+ {Py_tp_traverse, comerror_traverse},
+ {Py_tp_dealloc, comerror_dealloc},
+ {0, NULL},
};
+
+static PyType_Spec comerror_spec = {
+ .name = "_ctypes.COMError",
+ .basicsize = sizeof(PyBaseExceptionObject),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = comerror_slots,
+};
+
#endif // MS_WIN32
static PyObject *
@@ -5661,8 +5649,9 @@ _ctypes_add_types(PyObject *mod)
} \
} while (0)
-#define CREATE_TYPE(MOD, TP, SPEC) do { \
- PyObject *type = PyType_FromMetaclass(NULL, MOD, SPEC, NULL); \
+#define CREATE_TYPE(MOD, TP, SPEC, BASE) do { \
+ PyObject *type = PyType_FromMetaclass(NULL, MOD, SPEC, \
+ (PyObject *)BASE); \
if (type == NULL) { \
return -1; \
} \
@@ -5675,8 +5664,8 @@ _ctypes_add_types(PyObject *mod)
ob_type is the metatype (the 'type'), defaults to PyType_Type,
tp_base is the base type, defaults to 'object' aka PyBaseObject_Type.
*/
- CREATE_TYPE(mod, st->PyCArg_Type, &carg_spec);
- CREATE_TYPE(mod, st->PyCThunk_Type, &cthunk_spec);
+ CREATE_TYPE(mod, st->PyCArg_Type, &carg_spec, NULL);
+ CREATE_TYPE(mod, st->PyCThunk_Type, &cthunk_spec, NULL);
TYPE_READY(&PyCData_Type);
/* StgDict is derived from PyDict_Type */
TYPE_READY_BASE(&PyCStgDict_Type, &PyDict_Type);
@@ -5709,18 +5698,18 @@ _ctypes_add_types(PyObject *mod)
* Simple classes
*/
- CREATE_TYPE(mod, st->PyCField_Type, &cfield_spec);
+ CREATE_TYPE(mod, st->PyCField_Type, &cfield_spec, NULL);
/*************************************************
*
* Other stuff
*/
- CREATE_TYPE(mod, st->DictRemover_Type, &dictremover_spec);
- CREATE_TYPE(mod, st->StructParam_Type, &structparam_spec);
+ CREATE_TYPE(mod, st->DictRemover_Type, &dictremover_spec, NULL);
+ CREATE_TYPE(mod, st->StructParam_Type, &structparam_spec, NULL);
#ifdef MS_WIN32
- TYPE_READY_BASE(&PyComError_Type, (PyTypeObject*)PyExc_Exception);
+ CREATE_TYPE(mod, st->PyComError_Type, &comerror_spec, PyExc_Exception);
#endif
#undef TYPE_READY
@@ -5750,7 +5739,8 @@ _ctypes_add_objects(PyObject *mod)
MOD_ADD("_pointer_type_cache", Py_NewRef(_ctypes_ptrtype_cache));
#ifdef MS_WIN32
- MOD_ADD("COMError", Py_NewRef(ComError));
+ ctypes_state *st = GLOBAL_STATE();
+ MOD_ADD("COMError", Py_NewRef(st->PyComError_Type));
MOD_ADD("FUNCFLAG_HRESULT", PyLong_FromLong(FUNCFLAG_HRESULT));
MOD_ADD("FUNCFLAG_STDCALL", PyLong_FromLong(FUNCFLAG_STDCALL));
#endif
@@ -5807,9 +5797,6 @@ _ctypes_mod_exec(PyObject *mod)
if (_ctypes_add_types(mod) < 0) {
return -1;
}
-#ifdef MS_WIN32
- ComError = (PyObject*)&PyComError_Type;
-#endif
if (_ctypes_add_objects(mod) < 0) {
return -1;
diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c
index f10cf58216ac..d2fe525dd4d3 100644
--- a/Modules/_ctypes/callproc.c
+++ b/Modules/_ctypes/callproc.c
@@ -1115,7 +1115,8 @@ GetComError(HRESULT errcode, GUID *riid, IUnknown *pIunk)
descr, source, helpfile, helpcontext,
progid);
if (obj) {
- PyErr_SetObject(ComError, obj);
+ ctypes_state *st = GLOBAL_STATE();
+ PyErr_SetObject((PyObject *)st->PyComError_Type, obj);
Py_DECREF(obj);
}
LocalFree(text);
diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h
index 252d9da7dbb5..8891a0a741de 100644
--- a/Modules/_ctypes/ctypes.h
+++ b/Modules/_ctypes/ctypes.h
@@ -37,6 +37,9 @@ typedef struct {
PyTypeObject *PyCArg_Type;
PyTypeObject *PyCField_Type;
PyTypeObject *PyCThunk_Type;
+#ifdef MS_WIN32
+ PyTypeObject *PyComError_Type;
+#endif
PyTypeObject *StructParam_Type;
} ctypes_state;
@@ -392,10 +395,6 @@ extern int _ctypes_simple_instance(PyObject *obj);
extern PyObject *_ctypes_ptrtype_cache;
PyObject *_ctypes_get_errobj(int **pspace);
-#ifdef MS_WIN32
-extern PyObject *ComError;
-#endif
-
#ifdef USING_MALLOC_CLOSURE_DOT_C
void Py_ffi_closure_free(void *p);
void *Py_ffi_closure_alloc(size_t size, void** codeloc);
More information about the Python-checkins
mailing list