11// types.Union -- used to represent e.g. Union[int, str], int | str
22#include "Python.h"
3+ #include "pycore_object.h" // _PyObject_GC_TRACK/UNTRACK
34#include "pycore_unionobject.h"
45#include "structmember.h"
56
@@ -14,10 +15,20 @@ unionobject_dealloc(PyObject *self)
1415{
1516 unionobject * alias = (unionobject * )self ;
1617
18+ _PyObject_GC_UNTRACK (self );
19+
1720 Py_XDECREF (alias -> args );
1821 Py_TYPE (self )-> tp_free (self );
1922}
2023
24+ static int
25+ union_traverse (PyObject * self , visitproc visit , void * arg )
26+ {
27+ unionobject * alias = (unionobject * )self ;
28+ Py_VISIT (alias -> args );
29+ return 0 ;
30+ }
31+
2132static Py_hash_t
2233union_hash (PyObject * self )
2334{
@@ -437,8 +448,9 @@ PyTypeObject _Py_UnionType = {
437448 .tp_basicsize = sizeof (unionobject ),
438449 .tp_dealloc = unionobject_dealloc ,
439450 .tp_alloc = PyType_GenericAlloc ,
440- .tp_free = PyObject_Del ,
441- .tp_flags = Py_TPFLAGS_DEFAULT ,
451+ .tp_free = PyObject_GC_Del ,
452+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC ,
453+ .tp_traverse = union_traverse ,
442454 .tp_hash = union_hash ,
443455 .tp_getattro = PyObject_GenericGetAttr ,
444456 .tp_members = union_members ,
@@ -472,15 +484,16 @@ _Py_Union(PyObject *args)
472484 }
473485 }
474486
475- result = PyObject_New (unionobject , & _Py_UnionType );
487+ result = PyObject_GC_New (unionobject , & _Py_UnionType );
476488 if (result == NULL ) {
477489 return NULL ;
478490 }
479491
480492 result -> args = dedup_and_flatten_args (args );
481493 if (result -> args == NULL ) {
482- Py_DECREF (result );
494+ PyObject_GC_Del (result );
483495 return NULL ;
484496 }
497+ _PyObject_GC_TRACK (result );
485498 return (PyObject * )result ;
486499}
0 commit comments