[Python-checkins] bpo-42972: Fully implement GC protocol for re types (GH-26368) (GH-26414)

vstinner webhook-mailer at python.org
Thu May 27 20:23:52 EDT 2021


https://github.com/python/cpython/commit/da9e0cb4dedf818540ad1f06305bb1ca9e568f51
commit: da9e0cb4dedf818540ad1f06305bb1ca9e568f51
branch: 3.10
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: vstinner <vstinner at python.org>
date: 2021-05-28T02:23:37+02:00
summary:

bpo-42972: Fully implement GC protocol for re types (GH-26368) (GH-26414)

(cherry picked from commit fba42d11880f444bb94d9891e3949f082a57b9a9)

Co-authored-by: Erlend Egeberg Aasland <erlend.aasland at innova.no>

files:
M Modules/_sre.c

diff --git a/Modules/_sre.c b/Modules/_sre.c
index 9d0fc4ab7c03a..7b21240e9a033 100644
--- a/Modules/_sre.c
+++ b/Modules/_sre.c
@@ -562,17 +562,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);
 }
 
@@ -1396,7 +1415,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;
@@ -1416,6 +1435,7 @@ _sre_compile_impl(PyObject *module, PyObject *pattern, int flags,
             break;
         }
     }
+    PyObject_GC_Track(self);
 
     if (PyErr_Occurred()) {
         Py_DECREF(self);
@@ -1937,15 +1957,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);
 }
 
@@ -2391,9 +2429,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;
 
@@ -2426,6 +2464,7 @@ pattern_new_match(_sremodulestate* module_state,
 
         match->lastindex = state->lastindex;
 
+        PyObject_GC_Track(match);
         return (PyObject*) match;
 
     } else if (status == 0) {
@@ -2444,14 +2483,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);
 }
 
@@ -2548,7 +2603,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;
@@ -2562,6 +2617,7 @@ pattern_scanner(_sremodulestate *module_state,
     Py_INCREF(self);
     scanner->pattern = (PyObject*) self;
 
+    PyObject_GC_Track(scanner);
     return (PyObject*) scanner;
 }
 
@@ -2683,6 +2739,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},
 };
 
@@ -2691,7 +2749,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,
 };
 
@@ -2741,6 +2799,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.
      *
@@ -2757,7 +2817,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,
 };
 
@@ -2777,6 +2837,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},
 };
 
@@ -2784,7 +2846,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,
 };
 



More information about the Python-checkins mailing list