Skip to content

Commit fba42d1

Browse files
author
Erlend Egeberg Aasland
authored
bpo-42972: Fully implement GC protocol for re types (GH-26368)
1 parent 164a4f4 commit fba42d1

File tree

1 file changed

+81
-19
lines changed

1 file changed

+81
-19
lines changed

Modules/_sre.c

Lines changed: 81 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -563,17 +563,36 @@ pattern_error(Py_ssize_t status)
563563
}
564564
}
565565

566+
static int
567+
pattern_traverse(PatternObject *self, visitproc visit, void *arg)
568+
{
569+
Py_VISIT(Py_TYPE(self));
570+
Py_VISIT(self->groupindex);
571+
Py_VISIT(self->indexgroup);
572+
Py_VISIT(self->pattern);
573+
return 0;
574+
}
575+
576+
static int
577+
pattern_clear(PatternObject *self)
578+
{
579+
Py_CLEAR(self->groupindex);
580+
Py_CLEAR(self->indexgroup);
581+
Py_CLEAR(self->pattern);
582+
return 0;
583+
}
584+
566585
static void
567586
pattern_dealloc(PatternObject* self)
568587
{
569588
PyTypeObject *tp = Py_TYPE(self);
570589

571-
if (self->weakreflist != NULL)
590+
PyObject_GC_UnTrack(self);
591+
if (self->weakreflist != NULL) {
572592
PyObject_ClearWeakRefs((PyObject *) self);
573-
Py_XDECREF(self->pattern);
574-
Py_XDECREF(self->groupindex);
575-
Py_XDECREF(self->indexgroup);
576-
PyObject_Free(self);
593+
}
594+
(void)pattern_clear(self);
595+
tp->tp_free(self);
577596
Py_DECREF(tp);
578597
}
579598

@@ -1397,7 +1416,7 @@ _sre_compile_impl(PyObject *module, PyObject *pattern, int flags,
13971416

13981417
n = PyList_GET_SIZE(code);
13991418
/* coverity[ampersand_in_size] */
1400-
self = PyObject_NewVar(PatternObject, module_state->Pattern_Type, n);
1419+
self = PyObject_GC_NewVar(PatternObject, module_state->Pattern_Type, n);
14011420
if (!self)
14021421
return NULL;
14031422
self->weakreflist = NULL;
@@ -1417,6 +1436,7 @@ _sre_compile_impl(PyObject *module, PyObject *pattern, int flags,
14171436
break;
14181437
}
14191438
}
1439+
PyObject_GC_Track(self);
14201440

14211441
if (PyErr_Occurred()) {
14221442
Py_DECREF(self);
@@ -1938,15 +1958,33 @@ _validate(PatternObject *self)
19381958
/* -------------------------------------------------------------------- */
19391959
/* match methods */
19401960

1961+
static int
1962+
match_traverse(MatchObject *self, visitproc visit, void *arg)
1963+
{
1964+
Py_VISIT(Py_TYPE(self));
1965+
Py_VISIT(self->string);
1966+
Py_VISIT(self->regs);
1967+
Py_VISIT(self->pattern);
1968+
return 0;
1969+
}
1970+
1971+
static int
1972+
match_clear(MatchObject *self)
1973+
{
1974+
Py_CLEAR(self->string);
1975+
Py_CLEAR(self->regs);
1976+
Py_CLEAR(self->pattern);
1977+
return 0;
1978+
}
1979+
19411980
static void
19421981
match_dealloc(MatchObject* self)
19431982
{
19441983
PyTypeObject *tp = Py_TYPE(self);
19451984

1946-
Py_XDECREF(self->regs);
1947-
Py_XDECREF(self->string);
1948-
Py_DECREF(self->pattern);
1949-
PyObject_Free(self);
1985+
PyObject_GC_UnTrack(self);
1986+
(void)match_clear(self);
1987+
tp->tp_free(self);
19501988
Py_DECREF(tp);
19511989
}
19521990

@@ -2392,9 +2430,9 @@ pattern_new_match(_sremodulestate* module_state,
23922430

23932431
/* create match object (with room for extra group marks) */
23942432
/* coverity[ampersand_in_size] */
2395-
match = PyObject_NewVar(MatchObject,
2396-
module_state->Match_Type,
2397-
2*(pattern->groups+1));
2433+
match = PyObject_GC_NewVar(MatchObject,
2434+
module_state->Match_Type,
2435+
2*(pattern->groups+1));
23982436
if (!match)
23992437
return NULL;
24002438

@@ -2427,6 +2465,7 @@ pattern_new_match(_sremodulestate* module_state,
24272465

24282466
match->lastindex = state->lastindex;
24292467

2468+
PyObject_GC_Track(match);
24302469
return (PyObject*) match;
24312470

24322471
} else if (status == 0) {
@@ -2445,14 +2484,30 @@ pattern_new_match(_sremodulestate* module_state,
24452484
/* -------------------------------------------------------------------- */
24462485
/* scanner methods (experimental) */
24472486

2487+
static int
2488+
scanner_traverse(ScannerObject *self, visitproc visit, void *arg)
2489+
{
2490+
Py_VISIT(Py_TYPE(self));
2491+
Py_VISIT(self->pattern);
2492+
return 0;
2493+
}
2494+
2495+
static int
2496+
scanner_clear(ScannerObject *self)
2497+
{
2498+
Py_CLEAR(self->pattern);
2499+
return 0;
2500+
}
2501+
24482502
static void
24492503
scanner_dealloc(ScannerObject* self)
24502504
{
24512505
PyTypeObject *tp = Py_TYPE(self);
24522506

2507+
PyObject_GC_UnTrack(self);
24532508
state_fini(&self->state);
2454-
Py_XDECREF(self->pattern);
2455-
PyObject_Free(self);
2509+
(void)scanner_clear(self);
2510+
tp->tp_free(self);
24562511
Py_DECREF(tp);
24572512
}
24582513

@@ -2549,7 +2604,7 @@ pattern_scanner(_sremodulestate *module_state,
25492604
ScannerObject* scanner;
25502605

25512606
/* create scanner object */
2552-
scanner = PyObject_New(ScannerObject, module_state->Scanner_Type);
2607+
scanner = PyObject_GC_New(ScannerObject, module_state->Scanner_Type);
25532608
if (!scanner)
25542609
return NULL;
25552610
scanner->pattern = NULL;
@@ -2563,6 +2618,7 @@ pattern_scanner(_sremodulestate *module_state,
25632618
Py_INCREF(self);
25642619
scanner->pattern = (PyObject*) self;
25652620

2621+
PyObject_GC_Track(scanner);
25662622
return (PyObject*) scanner;
25672623
}
25682624

@@ -2684,6 +2740,8 @@ static PyType_Slot pattern_slots[] = {
26842740
{Py_tp_methods, pattern_methods},
26852741
{Py_tp_members, pattern_members},
26862742
{Py_tp_getset, pattern_getset},
2743+
{Py_tp_traverse, pattern_traverse},
2744+
{Py_tp_clear, pattern_clear},
26872745
{0, NULL},
26882746
};
26892747

@@ -2692,7 +2750,7 @@ static PyType_Spec pattern_spec = {
26922750
.basicsize = sizeof(PatternObject),
26932751
.itemsize = sizeof(SRE_CODE),
26942752
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE |
2695-
Py_TPFLAGS_DISALLOW_INSTANTIATION),
2753+
Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_HAVE_GC),
26962754
.slots = pattern_slots,
26972755
};
26982756

@@ -2742,6 +2800,8 @@ static PyType_Slot match_slots[] = {
27422800
{Py_tp_methods, match_methods},
27432801
{Py_tp_members, match_members},
27442802
{Py_tp_getset, match_getset},
2803+
{Py_tp_traverse, match_traverse},
2804+
{Py_tp_clear, match_clear},
27452805

27462806
/* As mapping.
27472807
*
@@ -2758,7 +2818,7 @@ static PyType_Spec match_spec = {
27582818
.basicsize = sizeof(MatchObject),
27592819
.itemsize = sizeof(Py_ssize_t),
27602820
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE |
2761-
Py_TPFLAGS_DISALLOW_INSTANTIATION),
2821+
Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_HAVE_GC),
27622822
.slots = match_slots,
27632823
};
27642824

@@ -2778,14 +2838,16 @@ static PyType_Slot scanner_slots[] = {
27782838
{Py_tp_dealloc, scanner_dealloc},
27792839
{Py_tp_methods, scanner_methods},
27802840
{Py_tp_members, scanner_members},
2841+
{Py_tp_traverse, scanner_traverse},
2842+
{Py_tp_clear, scanner_clear},
27812843
{0, NULL},
27822844
};
27832845

27842846
static PyType_Spec scanner_spec = {
27852847
.name = "_" SRE_MODULE ".SRE_Scanner",
27862848
.basicsize = sizeof(ScannerObject),
27872849
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE |
2788-
Py_TPFLAGS_DISALLOW_INSTANTIATION),
2850+
Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_HAVE_GC),
27892851
.slots = scanner_slots,
27902852
};
27912853

0 commit comments

Comments
 (0)