Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 36 additions & 73 deletions Modules/_ctypes/_ctypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -441,19 +441,35 @@ 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);
Py_CLEAR(info->argtypes);
Py_CLEAR(info->converters);
Py_CLEAR(info->restype);
Py_CLEAR(info->checker);
Py_CLEAR(info->module);
}

static int
Expand All @@ -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
Expand All @@ -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);
}
}

Expand Down Expand Up @@ -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.")},
Expand All @@ -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},
};

Expand Down Expand Up @@ -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,
Expand All @@ -988,35 +1010,6 @@ CDataType_repeat(PyObject *self, Py_ssize_t length)
return PyCArrayType_from_ctype(st, self, 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)
{
Expand Down Expand Up @@ -1047,39 +1040,29 @@ 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,
};

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,
};
Expand Down Expand Up @@ -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,
};
Expand Down Expand Up @@ -1640,19 +1618,14 @@ PyCArrayType_init(PyObject *self, PyObject *args, PyObject *kwds)

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,
};
Expand Down Expand Up @@ -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,
};
Expand Down Expand Up @@ -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,
};
Expand Down
8 changes: 8 additions & 0 deletions Modules/_ctypes/ctypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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);

Expand Down Expand Up @@ -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;
}
2 changes: 2 additions & 0 deletions Modules/_ctypes/stgdict.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down