Skip to content

Commit 2dee91e

Browse files
committed
make GraphemeClusterIterator a GC type
1 parent c9848e2 commit 2dee91e

File tree

1 file changed

+34
-23
lines changed

1 file changed

+34
-23
lines changed

Modules/unicodedata.c

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -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 *
13471357
unicodedata_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

Comments
 (0)