@@ -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
6396struct 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
593629static 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
599641static struct PyModuleDef_Slot multimerge_slots [] = {
@@ -604,9 +646,13 @@ static struct PyModuleDef_Slot multimerge_slots[] = {
604646static 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\
608651replacement 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
612658PyMODINIT_FUNC
0 commit comments