summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorErlend Egeberg Aasland <erlend.aasland@innova.no>2021-05-27 17:23:07 (GMT)
committerGitHub <noreply@github.com>2021-05-27 17:23:07 (GMT)
commitfba42d11880f444bb94d9891e3949f082a57b9a9 (patch)
tree5b7ede874a087a0384add5679aad8bff56932ae4 /Modules
parent164a4f46d1606e21d82babc010e397a9116e6730 (diff)
downloadcpython-fba42d11880f444bb94d9891e3949f082a57b9a9.zip
cpython-fba42d11880f444bb94d9891e3949f082a57b9a9.tar.gz
cpython-fba42d11880f444bb94d9891e3949f082a57b9a9.tar.bz2
bpo-42972: Fully implement GC protocol for re types (GH-26368)
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_sre.c100
1 files changed, 81 insertions, 19 deletions
diff --git a/Modules/_sre.c b/Modules/_sre.c
index a313ea1..d863ae0 100644
--- a/Modules/_sre.c
+++ b/Modules/_sre.c
@@ -563,17 +563,36 @@ pattern_error(Py_ssize_t status)
}
}
+static int
+pattern_traverse(PatternObject *self, visitproc visit, void *arg)
+{
+ Py_VISIT(Py_TYPE(self));
+ Py_VISIT(self->groupindex);
+ Py_VISIT(self->indexgroup);
+ Py_VISIT(self->pattern);
+ return 0;
+}
+
+static int
+pattern_clear(PatternObject *self)
+{
+ Py_CLEAR(self->groupindex);
+ Py_CLEAR(self->indexgroup);
+ Py_CLEAR(self->pattern);
+ return 0;
+}
+
static void
pattern_dealloc(PatternObject* self)
{
PyTypeObject *tp = Py_TYPE(self);
- if (self->weakreflist != NULL)
+ PyObject_GC_UnTrack(self);
+ if (self->weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject *) self);
- Py_XDECREF(self->pattern);
- Py_XDECREF(self->groupindex);
- Py_XDECREF(self->indexgroup);
- PyObject_Free(self);
+ }
+ (void)pattern_clear(self);
+ tp->tp_free(self);
Py_DECREF(tp);
}
@@ -1397,7 +1416,7 @@ _sre_compile_impl(PyObject *module, PyObject *pattern, int flags,
n = PyList_GET_SIZE(code);
/* coverity[ampersand_in_size] */
- self = PyObject_NewVar(PatternObject, module_state->Pattern_Type, n);
+ self = PyObject_GC_NewVar(PatternObject, module_state->Pattern_Type, n);
if (!self)
return NULL;
self->weakreflist = NULL;
@@ -1417,6 +1436,7 @@ _sre_compile_impl(PyObject *module, PyObject *pattern, int flags,
break;
}
}
+ PyObject_GC_Track(self);
if (PyErr_Occurred()) {
Py_DECREF(self);
@@ -1938,15 +1958,33 @@ _validate(PatternObject *self)
/* -------------------------------------------------------------------- */
/* match methods */
+static int
+match_traverse(MatchObject *self, visitproc visit, void *arg)
+{
+ Py_VISIT(Py_TYPE(self));
+ Py_VISIT(self->string);
+ Py_VISIT(self->regs);
+ Py_VISIT(self->pattern);
+ return 0;
+}
+
+static int
+match_clear(MatchObject *self)
+{
+ Py_CLEAR(self->string);
+ Py_CLEAR(self->regs);
+ Py_CLEAR(self->pattern);
+ return 0;
+}
+
static void
match_dealloc(MatchObject* self)
{
PyTypeObject *tp = Py_TYPE(self);
- Py_XDECREF(self->regs);
- Py_XDECREF(self->string);
- Py_DECREF(self->pattern);
- PyObject_Free(self);
+ PyObject_GC_UnTrack(self);
+ (void)match_clear(self);
+ tp->tp_free(self);
Py_DECREF(tp);
}
@@ -2392,9 +2430,9 @@ pattern_new_match(_sremodulestate* module_state,
/* create match object (with room for extra group marks) */
/* coverity[ampersand_in_size] */
- match = PyObject_NewVar(MatchObject,
- module_state->Match_Type,
- 2*(pattern->groups+1));
+ match = PyObject_GC_NewVar(MatchObject,
+ module_state->Match_Type,
+ 2*(pattern->groups+1));
if (!match)
return NULL;
@@ -2427,6 +2465,7 @@ pattern_new_match(_sremodulestate* module_state,
match->lastindex = state->lastindex;
+ PyObject_GC_Track(match);
return (PyObject*) match;
} else if (status == 0) {
@@ -2445,14 +2484,30 @@ pattern_new_match(_sremodulestate* module_state,
/* -------------------------------------------------------------------- */
/* scanner methods (experimental) */
+static int
+scanner_traverse(ScannerObject *self, visitproc visit, void *arg)
+{
+ Py_VISIT(Py_TYPE(self));
+ Py_VISIT(self->pattern);
+ return 0;
+}
+
+static int
+scanner_clear(ScannerObject *self)
+{
+ Py_CLEAR(self->pattern);
+ return 0;
+}
+
static void
scanner_dealloc(ScannerObject* self)
{
PyTypeObject *tp = Py_TYPE(self);
+ PyObject_GC_UnTrack(self);
state_fini(&self->state);
- Py_XDECREF(self->pattern);
- PyObject_Free(self);
+ (void)scanner_clear(self);
+ tp->tp_free(self);
Py_DECREF(tp);
}
@@ -2549,7 +2604,7 @@ pattern_scanner(_sremodulestate *module_state,
ScannerObject* scanner;
/* create scanner object */
- scanner = PyObject_New(ScannerObject, module_state->Scanner_Type);
+ scanner = PyObject_GC_New(ScannerObject, module_state->Scanner_Type);
if (!scanner)
return NULL;
scanner->pattern = NULL;
@@ -2563,6 +2618,7 @@ pattern_scanner(_sremodulestate *module_state,
Py_INCREF(self);
scanner->pattern = (PyObject*) self;
+ PyObject_GC_Track(scanner);
return (PyObject*) scanner;
}
@@ -2684,6 +2740,8 @@ static PyType_Slot pattern_slots[] = {
{Py_tp_methods, pattern_methods},
{Py_tp_members, pattern_members},
{Py_tp_getset, pattern_getset},
+ {Py_tp_traverse, pattern_traverse},
+ {Py_tp_clear, pattern_clear},
{0, NULL},
};
@@ -2692,7 +2750,7 @@ static PyType_Spec pattern_spec = {
.basicsize = sizeof(PatternObject),
.itemsize = sizeof(SRE_CODE),
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE |
- Py_TPFLAGS_DISALLOW_INSTANTIATION),
+ Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_HAVE_GC),
.slots = pattern_slots,
};
@@ -2742,6 +2800,8 @@ static PyType_Slot match_slots[] = {
{Py_tp_methods, match_methods},
{Py_tp_members, match_members},
{Py_tp_getset, match_getset},
+ {Py_tp_traverse, match_traverse},
+ {Py_tp_clear, match_clear},
/* As mapping.
*
@@ -2758,7 +2818,7 @@ static PyType_Spec match_spec = {
.basicsize = sizeof(MatchObject),
.itemsize = sizeof(Py_ssize_t),
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE |
- Py_TPFLAGS_DISALLOW_INSTANTIATION),
+ Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_HAVE_GC),
.slots = match_slots,
};
@@ -2778,6 +2838,8 @@ static PyType_Slot scanner_slots[] = {
{Py_tp_dealloc, scanner_dealloc},
{Py_tp_methods, scanner_methods},
{Py_tp_members, scanner_members},
+ {Py_tp_traverse, scanner_traverse},
+ {Py_tp_clear, scanner_clear},
{0, NULL},
};
@@ -2785,7 +2847,7 @@ static PyType_Spec scanner_spec = {
.name = "_" SRE_MODULE ".SRE_Scanner",
.basicsize = sizeof(ScannerObject),
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE |
- Py_TPFLAGS_DISALLOW_INSTANTIATION),
+ Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_HAVE_GC),
.slots = scanner_slots,
};