8000 gh-117142: ctypes: Unify meta tp slot functions (GH-117143) · python/cpython@dd44ab9 · GitHub
[go: up one dir, main page]

Skip to content

Commit dd44ab9

Browse files
authored
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()`.
1 parent 3de09ca commit dd44ab9

File tree

3 files changed

+46
-73
lines changed

3 files changed

+46
-73
lines changed

Modules/_ctypes/_ctypes.c

Lines changed: 36 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -441,19 +441,35 @@ static PyType_Spec structparam_spec = {
441441
static int
442442
CType_Type_traverse(PyObject *self, visitproc visit, void *arg)
443443
{
444+
ctypes_state *st = GLOBAL_STATE();
445+
if (st && st->PyCType_Type) {
446+
StgInfo *info;
447+
if (PyStgInfo_FromType(st, self, &info) < 0) {
448+
PyErr_WriteUnraisable(self);
449+
}
450+
if (info) {
451+
Py_VISIT(info->proto);
452+
Py_VISIT(info->argtypes);
453+
Py_VISIT(info->converters);
454+
Py_VISIT(info->restype);
455+
Py_VISIT(info->checker);
456+
Py_VISIT(info->module);
457+
}
458+
}
444459
Py_VISIT(Py_TYPE(self));
445-
return 0;
460+
return PyType_Type.tp_traverse(self, visit, arg);
446461
}
447462

448-
static void
449-
_ctype_clear_stginfo(StgInfo *info)
463+
void
464+
ctype_clear_stginfo(StgInfo *info)
450465
{
451466
assert(info);
452467
Py_CLEAR(info->proto);
453468
Py_CLEAR(info->argtypes);
454469
Py_CLEAR(info->converters);
455470
Py_CLEAR(info->restype);
456471
Py_CLEAR(info->checker);
472+
Py_CLEAR(info->module);
457473
}
458474

459475
static int
@@ -463,13 +479,13 @@ CType_Type_clear(PyObject *self)
463479
if (st && st->PyCType_Type) {
464480
StgInfo *info;
465481
if (PyStgInfo_FromType(st, self, &info) < 0) {
466-
return -1;
482+
PyErr_WriteUnraisable(self);
467483
}
468484
if (info) {
469-
_ctype_clear_stginfo(info);
485+
ctype_clear_stginfo(info);
470486
}
471487
}
472-
return 0;
488+
return PyType_Type.tp_clear(self);
473489
}
474490

475491
static void
@@ -489,7 +505,7 @@ CType_Type_dealloc(PyObject *self)
489505
info->format = NULL;
490506
PyMem_Free(info->shape);
491507
info->shape = NULL;
492-
_ctype_clear_stginfo(info);
508+
ctype_clear_stginfo(info);
493509
}
494510
}
495511

@@ -522,6 +538,10 @@ CType_Type_sizeof(PyObject *self)
522538
return PyLong_FromSsize_t(size);
523539
}
524540

541+
static PyObject *
542+
CType_Type_repeat(PyObject *self, Py_ssize_t length);
543+
544+
525545
static PyMethodDef ctype_methods[] = {
526546
{"__sizeof__", _PyCFunction_CAST(CType_Type_sizeof),
527547
METH_NOARGS, PyDoc_STR("Return memory consumption of the type object.")},
@@ -533,6 +553,8 @@ static PyType_Slot ctype_type_slots[] = {
533553
{Py_tp_clear, CType_Type_clear},
534554
{Py_tp_dealloc, CType_Type_dealloc},
535555
{Py_tp_methods, ctype_methods},
556+
// Sequence protocol.
557+
{Py_sq_repeat, CType_Type_repeat},
536558
{0, NULL},
537559
};
538560

@@ -978,7 +1000,7 @@ static PyMethodDef CDataType_methods[] = {
9781000
};
9791001

9801002
static PyObject *
981-
CDataType_repeat(PyObject *self, Py_ssize_t length)
1003+
CType_Type_repeat(PyObject *self, Py_ssize_t length)
9821004
{
9831005
if (length < 0)
9841006
return PyErr_Format(PyExc_ValueError,
@@ -988,35 +1010,6 @@ CDataType_repeat(PyObject *self, Py_ssize_t length)
9881010
return PyCArrayType_from_ctype(st, self, length);
9891011
}
9901012

991-
static int
992-
CDataType_clear(PyTypeObject *self)
993-
{
994-
ctypes_state *st = GLOBAL_STATE();
995-
StgInfo *info;
996-
if (PyStgInfo_FromType(st, (PyObject *)self, &info) < 0) {
997-
return -1;
998-
}
999-
if (info) {
1000-
Py_CLEAR(info->proto);
1001-
}
1002-
return PyType_Type.tp_clear((PyObject *)self);
1003-
}
1004-
1005-
static int
1006-
CDataType_traverse(PyTypeObject *self, visitproc visit, void *arg)
1007-
{
1008-
ctypes_state *st = GLOBAL_STATE();
1009-
StgInfo *info;
1010-
if (PyStgInfo_FromType(st, (PyObject *)self, &info) < 0) {
1011-
return -1;
1012-
}
1013-
if (info) {
1014-
Py_VISIT(info->proto);
1015-
}
1016-
Py_VISIT(Py_TYPE(self));
1017-
return PyType_Type.tp_traverse((PyObject *)self, visit, arg);
1018-
}
1019-
10201013
static int
10211014
PyCStructType_setattro(PyObject *self, PyObject *key, PyObject *value)
10221015
{
@@ -1047,39 +1040,29 @@ UnionType_setattro(PyObject *self, PyObject *key, PyObject *value)
10471040
static PyType_Slot pycstruct_type_slots[] = {
10481041
{Py_tp_setattro, PyCStructType_setattro},
10491042
{Py_tp_doc, PyDoc_STR("metatype for the CData Objects")},
1050-
{Py_tp_traverse, CDataType_traverse},
1051-
{Py_tp_clear, CDataType_clear},
10521043
{Py_tp_methods, CDataType_methods},
10531044
{Py_tp_init, PyCStructType_init},
1054-
1055-
// Sequence protocol.
1056-
{Py_sq_repeat, CDataType_repeat},
10571045
{0, NULL},
10581046
};
10591047

10601048
static PyType_Spec pycstruct_type_spec = {
10611049
.name = "_ctypes.PyCStructType",
1062-
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
1050+
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
10631051
Py_TPFLAGS_IMMUTABLETYPE),
10641052
.slots = pycstruct_type_slots,
10651053
};
10661054

10671055
static PyType_Slot union_type_slots[] = {
10681056
{Py_tp_setattro, UnionType_setattro},
10691057
{Py_tp_doc, PyDoc_STR("metatype for the Union Objects")},
1070-
{Py_tp_traverse, CDataType_traverse},
1071-
{Py_tp_clear, CDataType_clear},
10721058
{Py_tp_methods, CDataType_methods},
10731059
{Py_tp_init, UnionType_init},
1074-
1075-
// Sequence protocol.
1076-
{Py_sq_repeat, CDataType_repeat},
10771060
{0, NULL},
10781061
};
10791062

10801063
static PyType_Spec union_type_spec = {
10811064
.name = "_ctypes.UnionType",
1082-
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
1065+
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
10831066
Py_TPFLAGS_IMMUTABLETYPE),
10841067
.slots = union_type_slots,
10851068
};
@@ -1305,19 +1288,14 @@ static PyMethodDef PyCPointerType_methods[] = {
13051288

13061289
static PyType_Slot pycpointer_type_slots[] = {
13071290
{Py_tp_doc, PyDoc_STR("metatype for the Pointer Objects")},
1308-
{Py_tp_traverse, CDataType_traverse},
1309-
{Py_tp_clear, CDataType_clear},
13101291
{Py_tp_methods, PyCPointerType_methods},
13111292
{Py_tp_init, PyCPointerType_init},
1312-
1313-
// Sequence protocol.
1314-
{Py_sq_repeat, CDataType_repeat},
13151293
{0, NULL},
13161294
};
13171295

13181296
static PyType_Spec pycpointer_type_spec = {
13191297
.name = "_ctypes.PyCPointerType",
1320-
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
1298+
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
13211299
Py_TPFLAGS_IMMUTABLETYPE),
13221300
.slots = pycpointer_type_slots,
13231301
};
@@ -1640,19 +1618,14 @@ PyCArrayType_init(PyObject *self, PyObject *args, PyObject *kwds)
16401618

16411619
static PyType_Slot pycarray_type_slots[] = {
16421620
{Py_tp_doc, PyDoc_STR("metatype for the Array Objects")},
1643-
{Py_tp_traverse, CDataType_traverse},
16441621
{Py_tp_methods, CDataType_methods},
16451622
{Py_tp_init, PyCArrayType_init},
1646-
{Py_tp_clear, CDataType_clear},
1647-
1648-
// Sequence protocol.
1649-
{Py_sq_repeat, CDataType_repeat},
16501623
{0, NULL},
16511624
};
16521625

16531626
static PyType_Spec pycarray_type_spec = {
16541627
.name = "_ctypes.PyCArrayType",
1655-
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
1628+
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
16561629
Py_TPFLAGS_IMMUTABLETYPE),
16571630
.slots = pycarray_type_slots,
16581631
};
@@ -2315,17 +2288,12 @@ static PyType_Slot pycsimple_type_slots[] = {
23152288
{Py_tp_doc, PyDoc_STR("metatype for the PyCSimpleType Objects")},
23162289
{Py_tp_methods, PyCSimpleType_methods},
23172290
{Py_tp_init, PyCSimpleType_init},
2318-
{Py_tp_traverse, CDataType_traverse},
2319-
{Py_tp_clear, CDataType_clear},
2320-
2321-
// Sequence protocol.
2322-
{Py_sq_repeat, CDataType_repeat},
23232291
{0, NULL},
23242292
};
23252293

23262294
static PyType_Spec pycsimple_type_spec = {
23272295
.name = "_ctypes.PyCSimpleType",
2328-
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
2296+
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
23292297
Py_TPFLAGS_IMMUTABLETYPE),
23302298
.slots = pycsimple_type_slots,
23312299
};
@@ -2570,19 +2538,14 @@ PyCFuncPtrType_init(PyObject *self, PyObject *args, PyObject *kwds)
25702538

25712539
static PyType_Slot pycfuncptr_type_slots[] = {
25722540
{Py_tp_doc, PyDoc_STR("metatype for C function pointers")},
2573-
{Py_tp_traverse, CDataType_traverse},
2574-
{Py_tp_clear, CDataType_clear},
25752541
{Py_tp_methods, CDataType_methods},
25762542
{Py_tp_init, PyCFuncPtrType_init},
2577-
2578-
// Sequence protocol.
2579-
{Py_sq_repeat, CDataType_repeat},
25802543
{0, NULL},
25812544
};
25822545

25832546
static PyType_Spec pycfuncptr_type_spec = {
25842547
.name = "_ctypes.PyCFuncPtrType",
2585-
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
2548+
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
25862549
Py_TPFLAGS_IMMUTABLETYPE),
25872550
.slots = pycfuncptr_type_slots,
25882551
};

Modules/_ctypes/ctypes.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ typedef struct {
302302
PyObject *converters; /* tuple([t.from_param for t in argtypes]) */
303303
PyObject *restype; /* CDataObject or NULL */
304304
PyObject *checker;
305+
PyObject *module;
305306
int flags; /* calling convention and such */
306307

307308
/* pep3118 fields, pointers need PyMem_Free */
@@ -313,6 +314,7 @@ typedef struct {
313314
} StgInfo;
314315

315316
extern int PyCStgInfo_clone(StgInfo *dst_info, StgInfo *src_info);
317+
extern void ctype_clear_stginfo(StgInfo *info);
316318

317319
typedef int(* PPROC)(void);
318320

@@ -481,6 +483,12 @@ PyStgInfo_Init(ctypes_state *state, PyTypeObject *type)
481483
type->tp_name);
482484
return NULL;
483485
}
486+
PyObject *module = PyType_GetModule(state->PyCType_Type);
487+
if (!module) {
488+
return NULL;
489+
}
490+
info->module = Py_NewRef(module);
491+
484492
info->initialized = 1;
485493
return info;
486494
}

Modules/_ctypes/stgdict.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ PyCStgInfo_clone(StgInfo *dst_info, StgInfo *src_info)
2525
{
2626
Py_ssize_t size;
2727

28+
ctype_clear_stginfo(dst_info);
2829
PyMem_Free(dst_info->ffi_type_pointer.elements);
2930
PyMem_Free(dst_info->format);
3031
dst_info->format = NULL;
@@ -39,6 +40,7 @@ PyCStgInfo_clone(StgInfo *dst_info, StgInfo *src_info)
3940
Py_XINCREF(dst_info->converters);
4041
Py_XINCREF(dst_info->restype);
4142
Py_XINCREF(dst_info->checker);
43+
Py_XINCREF(dst_info->module);
4244

4345
if (src_info->format) {
4446
dst_info->format = PyMem_Malloc(strlen(src_info->format) + 1);

0 commit comments

Comments
 (0)
0