@@ -1280,40 +1280,48 @@ typedef struct {
12801280 Py_ssize_t pos ;
12811281} GraphemeClusterIterator ;
12821282
1283- void GCI_Del (PyObject * x )
1283+ static void
1284+ GCI_dealloc (GraphemeClusterIterator * it )
12841285{
1285- GraphemeClusterIterator * i = (GraphemeClusterIterator * )x ;
1286- Py_DECREF (i -> str );
1287- PyObject_Del (x );
1286+ PyObject_GC_UnTrack (it );
1287+ Py_DECREF (it -> str );
1288+ PyObject_GC_Del (it );
1289+ }
1290+
1291+ static int
1292+ GCI_traverse (GraphemeClusterIterator * it , visitproc visit , void * arg ) {
1293+ Py_VISIT (it -> str );
1294+ return 0 ;
12881295}
12891296
1290- static PyObject * GCI_iter (PyObject * self )
1297+ static int
1298+ GCI_clear (GraphemeClusterIterator * self )
12911299{
1292- Py_INCREF (self );
1293- return self ;
1300+ Py_CLEAR (self -> str );
1301+ return 0 ;
12941302}
12951303
12961304#include "grapheme_cluster_break_automaton.h"
12971305
1298- PyObject * GCI_iternext (PyObject * self )
1306+ static PyObject *
1307+ GCI_iternext (GraphemeClusterIterator * self )
12991308{
1300- GraphemeClusterIterator * p = (GraphemeClusterIterator * )self ;
1301- int kind = PyUnicode_KIND (p -> str );
1302- void * pstr = PyUnicode_DATA (p -> str );
1303- if (PyUnicode_READ (kind , pstr , p -> pos )) {
1304- int start = p -> pos ;
1309+ int kind = PyUnicode_KIND (self -> str );
1310+ void * pstr = PyUnicode_DATA (self -> str );
1311+ if (PyUnicode_READ (kind , pstr , self -> pos )) {
1312+ int start = self -> pos ;
13051313 GCBState s = STATE_sot ;
13061314 while (1 ) {
1307- if (!PyUnicode_READ (kind , pstr , p -> pos )) {
1308- return PyUnicode_Substring (p -> str , start , p -> pos );
1315+ if (!PyUnicode_READ (kind , pstr , self -> pos )) {
1316+ return PyUnicode_Substring (self -> str , start , self -> pos );
13091317 }
1310- Py_UCS4 chr = PyUnicode_READ (kind , pstr , p -> pos );
1318+ Py_UCS4 chr = PyUnicode_READ (kind , pstr , self -> pos );
13111319 int prop = _getrecord_ex (chr )-> grapheme_cluster_break ;
13121320 s = GRAPH_CLUSTER_AUTOMATON [s ][prop ];
13131321 if (s == STATE_BREAK ) {
1314- return PyUnicode_Substring (p -> str , start , p -> pos );
1322+ return PyUnicode_Substring (self -> str , start , self -> pos );
13151323 }
1316- ++ p -> pos ;
1324+ ++ self -> pos ;
13171325 }
13181326 } else {
13191327 return NULL ;
@@ -1324,11 +1332,13 @@ static PyTypeObject GraphemeClusterIteratorType = {
13241332 PyVarObject_HEAD_INIT (NULL , 0 )
13251333 .tp_name = "unicodedata.GraphemeClusterIterator" ,
13261334 .tp_basicsize = sizeof (GraphemeClusterIterator ),
1327- .tp_dealloc = (destructor )GCI_Del ,
1328- .tp_flags = Py_TPFLAGS_DEFAULT ,
1335+ .tp_dealloc = (destructor )GCI_dealloc ,
1336+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC ,
13291337 .tp_doc = "Internal grapheme cluster iterator object." ,
1330- .tp_iter = GCI_iter ,
1331- .tp_iternext = GCI_iternext
1338+ .tp_iter = PyObject_SelfIter ,
1339+ .tp_iternext = (iternextfunc )GCI_iternext ,
1340+ .tp_traverse = (traverseproc )GCI_traverse ,
1341+ .tp_clear = (inquiry )GCI_clear
13321342};
13331343
13341344/*[clinic input]
@@ -1347,14 +1357,15 @@ static PyObject *
13471357unicodedata_UCD_iter_graphemes_impl (PyObject * self , PyObject * unistr )
13481358/*[clinic end generated code: output=92374c1d94db4165 input=59c4794a7f2e6742]*/
13491359{
1350- GraphemeClusterIterator * gci = PyObject_New (GraphemeClusterIterator ,
1360+ GraphemeClusterIterator * gci = PyObject_GC_New (GraphemeClusterIterator ,
13511361 & GraphemeClusterIteratorType );
13521362
13531363 if (!gci )
13541364 return NULL ;
13551365
13561366 gci -> str = unistr ;
13571367 Py_INCREF (unistr );
1368+ PyObject_GC_Track (gci );
13581369 gci -> pos = 0 ;
13591370 return (PyObject * )gci ;
13601371}
0 commit comments