Skip to content

Commit a6b7c51

Browse files
authored
Use module state, no static types (#8)
1 parent 8a3397e commit a6b7c51

File tree

1 file changed

+61
-15
lines changed

1 file changed

+61
-15
lines changed

multimergemodule.c

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,39 @@ Algorithm for multimerge.merge:
5858
- The merge object holds the sole strong reference to the root.
5959
*/
6060

61+
typedef struct merge_state {
62+
PyObject *merge_type;
63+
} merge_state;
64+
65+
static merge_state *
66+
get_merge_state(PyObject *module)
67+
{
68+
return (merge_state *)PyModule_GetState(module);
69+
}
70+
71+
static int
72+
mergemodule_traverse(PyObject *module, visitproc visit, void *arg)
73+
{
74+
merge_state *state = get_merge_state(module);
75+
Py_VISIT(state->merge_type);
76+
return 0;
77+
}
78+
79+
static int
80+
mergemodule_clear(PyObject *module)
81+
{
82+
merge_state *state = get_merge_state(module);
83+
Py_CLEAR(state->merge_type);
84+
return 0;
85+
}
86+
87+
static void
88+
mergemodule_free(PyObject *module)
89+
{
90+
merge_state *state = get_merge_state(module);
91+
Py_CLEAR(state->merge_type);
92+
}
93+
6194
/* merge node object ********************************************************/
6295

6396
struct merge_node;
@@ -575,25 +608,34 @@ its sort order.\n\
575608
>>> list(merge(['dog', 'horse'], ['cat', 'fish', 'kangaroo'], key=len))\n\
576609
['dog', 'cat', 'fish', 'horse', 'kangaroo']");
577610

578-
static PyTypeObject merge_type = {
579-
PyVarObject_HEAD_INIT(NULL, 0)
580-
.tp_name = "multimerge.merge",
581-
.tp_basicsize = sizeof(mergeobject),
582-
.tp_dealloc = (destructor)merge_dealloc,
583-
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
584-
.tp_doc = merge_doc,
585-
.tp_traverse = (traverseproc)merge_traverse,
586-
.tp_clear = (inquiry)merge_clear,
587-
.tp_iter = PyObject_SelfIter,
588-
.tp_iternext = (iternextfunc)merge_next,
589-
.tp_new = merge_new,
590-
.tp_free = PyObject_GC_Del,
611+
static PyType_Slot merge_type_slots[] = {
612+
{Py_tp_dealloc, merge_dealloc},
613+
{Py_tp_doc, (void *)merge_doc},
614+
{Py_tp_traverse, merge_traverse},
615+
{Py_tp_clear, merge_clear},
616+
{Py_tp_iter, PyObject_SelfIter},
617+
{Py_tp_iternext, merge_next},
618+
{Py_tp_new, merge_new},
619+
{0, NULL},
620+
};
621+
622+
static PyType_Spec merge_type_spec = {
623+
.name = "multimerge.merge",
624+
.basicsize = sizeof(mergeobject),
625+
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
626+
.slots = merge_type_slots,
591627
};
592628

593629
static int
594-
multimerge_exec(PyObject *m)
630+
multimerge_exec(PyObject *module)
595631
{
596-
return PyModule_AddType(m, &merge_type);
632+
merge_state *state = get_merge_state(module);
633+
state->merge_type = PyType_FromModuleAndSpec(module,
634+
&merge_type_spec, NULL);
635+
if (state->merge_type == NULL) {
636+
return -1;
637+
}
638+
return PyModule_AddType(module, state->merge_type);
597639
}
598640

599641
static struct PyModuleDef_Slot multimerge_slots[] = {
@@ -604,9 +646,13 @@ static struct PyModuleDef_Slot multimerge_slots[] = {
604646
static struct PyModuleDef multimergemodule = {
605647
PyModuleDef_HEAD_INIT,
606648
.m_name = "multimerge",
649+
.m_size = sizeof(merge_state),
607650
.m_doc = "implements a k-way merge algorithm as a drop-in\n\
608651
replacement for heapq.merge in the Python standard library",
609652
.m_slots = multimerge_slots,
653+
.m_traverse = mergemodule_traverse,
654+
.m_clear = mergemodule_clear,
655+
.m_free = mergemodule_free,
610656
};
611657

612658
PyMODINIT_FUNC

0 commit comments

Comments
 (0)