summaryrefslogtreecommitdiffstats
path: root/Modules/_ctypes
diff options
context:
space:
mode:
authorneonene <53406459+neonene@users.noreply.github.com>2024-04-01 13:28:14 (GMT)
committerGitHub <noreply@github.com>2024-04-01 13:28:14 (GMT)
commitdd44ab994b7262f0704d64996e0a1bc37b233407 (patch)
tree571018340d10e412335e4e83d981bc43f59f20d7 /Modules/_ctypes
parent3de09cadde788065a4f2d45117e789c9353bbd12 (diff)
downloadcpython-dd44ab994b7262f0704d64996e0a1bc37b233407.zip
cpython-dd44ab994b7262f0704d64996e0a1bc37b233407.tar.gz
cpython-dd44ab994b7262f0704d64996e0a1bc37b233407.tar.bz2
gh-117142: ctypes: Unify meta tp slot functions (GH-117143)
Integrates the following ctypes meta tp slot functions: * `CDataType_traverse()` into `CType_Type_traverse()`. * `CDataType_clear()` into `CType_Type_clear()`. * `CDataType_dealloc()` into `CType_Type_dealloc()`. * `CDataType_repeat()` into `CType_Type_repeat()`.
Diffstat (limited to 'Modules/_ctypes')
-rw-r--r--Modules/_ctypes/_ctypes.c109
-rw-r--r--Modules/_ctypes/ctypes.h8
-rw-r--r--Modules/_ctypes/stgdict.c2
3 files changed, 46 insertions, 73 deletions
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
index 6bd1893..631f828 100644
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -441,12 +441,27 @@ static PyType_Spec structparam_spec = {
static int
CType_Type_traverse(PyObject *self, visitproc visit, void *arg)
{
+ ctypes_state *st = GLOBAL_STATE();
+ if (st && st->PyCType_Type) {
+ StgInfo *info;
+ if (PyStgInfo_FromType(st, self, &info) < 0) {
+ PyErr_WriteUnraisable(self);
+ }
+ if (info) {
+ Py_VISIT(info->proto);
+ Py_VISIT(info->argtypes);
+ Py_VISIT(info->converters);
+ Py_VISIT(info->restype);
+ Py_VISIT(info->checker);
+ Py_VISIT(info->module);
+ }
+ }
Py_VISIT(Py_TYPE(self));
- return 0;
+ return PyType_Type.tp_traverse(self, visit, arg);
}
-static void
-_ctype_clear_stginfo(StgInfo *info)
+void
+ctype_clear_stginfo(StgInfo *info)
{
assert(info);
Py_CLEAR(info->proto);
@@ -454,6 +469,7 @@ _ctype_clear_stginfo(StgInfo *info)
Py_CLEAR(info->converters);
Py_CLEAR(info->restype);
Py_CLEAR(info->checker);
+ Py_CLEAR(info->module);
}
static int
@@ -463,13 +479,13 @@ CType_Type_clear(PyObject *self)
if (st && st->PyCType_Type) {
StgInfo *info;
if (PyStgInfo_FromType(st, self, &info) < 0) {
- return -1;
+ PyErr_WriteUnraisable(self);
}
if (info) {
- _ctype_clear_stginfo(info);
+ ctype_clear_stginfo(info);
}
}
- return 0;
+ return PyType_Type.tp_clear(self);
}
static void
@@ -489,7 +505,7 @@ CType_Type_dealloc(PyObject *self)
info->format = NULL;
PyMem_Free(info->shape);
info->shape = NULL;
- _ctype_clear_stginfo(info);
+ ctype_clear_stginfo(info);
}
}
@@ -522,6 +538,10 @@ CType_Type_sizeof(PyObject *self)
return PyLong_FromSsize_t(size);
}
+static PyObject *
+CType_Type_repeat(PyObject *self, Py_ssize_t length);
+
+
static PyMethodDef ctype_methods[] = {
{"__sizeof__", _PyCFunction_CAST(CType_Type_sizeof),
METH_NOARGS, PyDoc_STR("Return memory consumption of the type object.")},
@@ -533,6 +553,8 @@ static PyType_Slot ctype_type_slots[] = {
{Py_tp_clear, CType_Type_clear},
{Py_tp_dealloc, CType_Type_dealloc},
{Py_tp_methods, ctype_methods},
+ // Sequence protocol.
+ {Py_sq_repeat, CType_Type_repeat},
{0, NULL},
};
@@ -978,7 +1000,7 @@ static PyMethodDef CDataType_methods[] = {
};
static PyObject *
-CDataType_repeat(PyObject *self, Py_ssize_t length)
+CType_Type_repeat(PyObject *self, Py_ssize_t length)
{
if (length < 0)
return PyErr_Format(PyExc_ValueError,
@@ -989,35 +1011,6 @@ CDataType_repeat(PyObject *self, Py_ssize_t length)
}
static int
-CDataType_clear(PyTypeObject *self)
-{
- ctypes_state *st = GLOBAL_STATE();
- StgInfo *info;
- if (PyStgInfo_FromType(st, (PyObject *)self, &info) < 0) {
- return -1;
- }
- if (info) {
- Py_CLEAR(info->proto);
- }
- return PyType_Type.tp_clear((PyObject *)self);
-}
-
-static int
-CDataType_traverse(PyTypeObject *self, visitproc visit, void *arg)
-{
- ctypes_state *st = GLOBAL_STATE();
- StgInfo *info;
- if (PyStgInfo_FromType(st, (PyObject *)self, &info) < 0) {
- return -1;
- }
- if (info) {
- Py_VISIT(info->proto);
- }
- Py_VISIT(Py_TYPE(self));
- return PyType_Type.tp_traverse((PyObject *)self, visit, arg);
-}
-
-static int
PyCStructType_setattro(PyObject *self, PyObject *key, PyObject *value)
{
/* XXX Should we disallow deleting _fields_? */
@@ -1047,19 +1040,14 @@ UnionType_setattro(PyObject *self, PyObject *key, PyObject *value)
static PyType_Slot pycstruct_type_slots[] = {
{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_init, PyCStructType_init},
-
- // Sequence protocol.
- {Py_sq_repeat, CDataType_repeat},
{0, NULL},
};
static PyType_Spec pycstruct_type_spec = {
.name = "_ctypes.PyCStructType",
- .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
Py_TPFLAGS_IMMUTABLETYPE),
.slots = pycstruct_type_slots,
};
@@ -1067,19 +1055,14 @@ static PyType_Spec pycstruct_type_spec = {
static PyType_Slot union_type_slots[] = {
{Py_tp_setattro, UnionType_setattro},
{Py_tp_doc, PyDoc_STR("metatype for the Union Objects")},
- {Py_tp_traverse, CDataType_traverse},
- {Py_tp_clear, CDataType_clear},
{Py_tp_methods, CDataType_methods},
{Py_tp_init, UnionType_init},
-
- // Sequence protocol.
- {Py_sq_repeat, CDataType_repeat},
{0, NULL},
};
static PyType_Spec union_type_spec = {
.name = "_ctypes.UnionType",
- .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
Py_TPFLAGS_IMMUTABLETYPE),
.slots = union_type_slots,
};
@@ -1305,19 +1288,14 @@ static PyMethodDef PyCPointerType_methods[] = {
static PyType_Slot pycpointer_type_slots[] = {
{Py_tp_doc, PyDoc_STR("metatype for the Pointer Objects")},
- {Py_tp_traverse, CDataType_traverse},
- {Py_tp_clear, CDataType_clear},
{Py_tp_methods, PyCPointerType_methods},
{Py_tp_init, PyCPointerType_init},
-
- // Sequence protocol.
- {Py_sq_repeat, CDataType_repeat},
{0, NULL},
};
static PyType_Spec pycpointer_type_spec = {
.name = "_ctypes.PyCPointerType",
- .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
Py_TPFLAGS_IMMUTABLETYPE),
.slots = pycpointer_type_slots,
};
@@ -1640,19 +1618,14 @@ error:
static PyType_Slot pycarray_type_slots[] = {
{Py_tp_doc, PyDoc_STR("metatype for the Array Objects")},
- {Py_tp_traverse, CDataType_traverse},
{Py_tp_methods, CDataType_methods},
{Py_tp_init, PyCArrayType_init},
- {Py_tp_clear, CDataType_clear},
-
- // Sequence protocol.
- {Py_sq_repeat, CDataType_repeat},
{0, NULL},
};
static PyType_Spec pycarray_type_spec = {
.name = "_ctypes.PyCArrayType",
- .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
Py_TPFLAGS_IMMUTABLETYPE),
.slots = pycarray_type_slots,
};
@@ -2315,17 +2288,12 @@ static PyType_Slot pycsimple_type_slots[] = {
{Py_tp_doc, PyDoc_STR("metatype for the PyCSimpleType Objects")},
{Py_tp_methods, PyCSimpleType_methods},
{Py_tp_init, PyCSimpleType_init},
- {Py_tp_traverse, CDataType_traverse},
- {Py_tp_clear, CDataType_clear},
-
- // Sequence protocol.
- {Py_sq_repeat, CDataType_repeat},
{0, NULL},
};
static PyType_Spec pycsimple_type_spec = {
.name = "_ctypes.PyCSimpleType",
- .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
Py_TPFLAGS_IMMUTABLETYPE),
.slots = pycsimple_type_slots,
};
@@ -2570,19 +2538,14 @@ PyCFuncPtrType_init(PyObject *self, PyObject *args, PyObject *kwds)
static PyType_Slot pycfuncptr_type_slots[] = {
{Py_tp_doc, PyDoc_STR("metatype for C function pointers")},
- {Py_tp_traverse, CDataType_traverse},
- {Py_tp_clear, CDataType_clear},
{Py_tp_methods, CDataType_methods},
{Py_tp_init, PyCFuncPtrType_init},
-
- // Sequence protocol.
- {Py_sq_repeat, CDataType_repeat},
{0, NULL},
};
static PyType_Spec pycfuncptr_type_spec = {
.name = "_ctypes.PyCFuncPtrType",
- .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
Py_TPFLAGS_IMMUTABLETYPE),
.slots = pycfuncptr_type_slots,
};
diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h
index 3422310..31b89dc 100644
--- a/Modules/_ctypes/ctypes.h
+++ b/Modules/_ctypes/ctypes.h
@@ -302,6 +302,7 @@ typedef struct {
PyObject *converters; /* tuple([t.from_param for t in argtypes]) */
PyObject *restype; /* CDataObject or NULL */
PyObject *checker;
+ PyObject *module;
int flags; /* calling convention and such */
/* pep3118 fields, pointers need PyMem_Free */
@@ -313,6 +314,7 @@ typedef struct {
} StgInfo;
extern int PyCStgInfo_clone(StgInfo *dst_info, StgInfo *src_info);
+extern void ctype_clear_stginfo(StgInfo *info);
typedef int(* PPROC)(void);
@@ -481,6 +483,12 @@ PyStgInfo_Init(ctypes_state *state, PyTypeObject *type)
type->tp_name);
return NULL;
}
+ PyObject *module = PyType_GetModule(state->PyCType_Type);
+ if (!module) {
+ return NULL;
+ }
+ info->module = Py_NewRef(module);
+
info->initialized = 1;
return info;
}
diff --git a/Modules/_ctypes/stgdict.c b/Modules/_ctypes/stgdict.c
index 53e7dc3..7b09bae 100644
--- a/Modules/_ctypes/stgdict.c
+++ b/Modules/_ctypes/stgdict.c
@@ -25,6 +25,7 @@ PyCStgInfo_clone(StgInfo *dst_info, StgInfo *src_info)
{
Py_ssize_t size;
+ ctype_clear_stginfo(dst_info);
PyMem_Free(dst_info->ffi_type_pointer.elements);
PyMem_Free(dst_info->format);
dst_info->format = NULL;
@@ -39,6 +40,7 @@ PyCStgInfo_clone(StgInfo *dst_info, StgInfo *src_info)
Py_XINCREF(dst_info->converters);
Py_XINCREF(dst_info->restype);
Py_XINCREF(dst_info->checker);
+ Py_XINCREF(dst_info->module);
if (src_info->format) {
dst_info->format = PyMem_Malloc(strlen(src_info->format) + 1);