https://github.com/python/cpython/commit/84e852736861a252affd15c479538c6f992111cc commit: 84e852736861a252affd15c479538c6f992111cc branch: 3.15 author: Miss Islington (bot) <[email protected]> committer: eendebakpt <[email protected]> date: 2026-11-03T11:27:15+01:00 summary:
[3.15] gh-158095: Fix reference cycles in re scanners (GH-158100) (#161246) gh-158095: Fix reference cycles in re scanners (GH-158100) * Fix reference cycles in re scanners * 📜🤖 Added by blurb_it. * gh-158095: Normalize NEWS line endings * gh-158095: Clear input references in re scanners * ci: rerun checks Assisted-by: Codex:GPT-6 --------- (cherry picked from commit 8c3b566891c4bf8a071588e3377ba933850d9501) Co-authored-by: sijun-yang <[email protected]> Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> files: A Misc/NEWS.d/next/Library/2026-09-24-14-59-08.gh-issue-158095.lcKOT4.rst M Lib/test/test_re.py M Modules/_sre/sre.c diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 00a4f325bc322c7..1217653fe272c79 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -8,6 +8,7 @@ import sys import unittest import warnings +import weakref from re import Scanner from weakref import proxy @@ -1735,6 +1736,27 @@ def test_finditer(self): self.assertEqual([item.group(0) for item in iter], ["::", "::"]) + def test_finditer_gc(self): + class Text(str): + pass + + class Buffer(bytearray): + pass + + text = Text('a') + text.iterator = re.finditer('a', text) + ref = weakref.ref(text) + del text + gc_collect() + self.assertIsNone(ref()) + + buffer = Buffer(b'a') + buffer.iterator = re.finditer(b'a', buffer) + ref = weakref.ref(buffer) + del buffer + gc_collect() + self.assertIsNone(ref()) + def test_bug_926075(self): self.assertIsNot(re.compile('bug_926075'), re.compile(b'bug_926075')) diff --git a/Misc/NEWS.d/next/Library/2026-09-24-14-59-08.gh-issue-158095.lcKOT4.rst b/Misc/NEWS.d/next/Library/2026-09-24-14-59-08.gh-issue-158095.lcKOT4.rst new file mode 100644 index 000000000000000..4fe92b8c8097d85 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-09-24-14-59-08.gh-issue-158095.lcKOT4.rst @@ -0,0 +1,2 @@ +Fix a memory leak in :func:`re.finditer` and regular expression scanners when +their input participates in a reference cycle. diff --git a/Modules/_sre/sre.c b/Modules/_sre/sre.c index 1eee31b3ee48235..90d66ee81e9a08b 100644 --- a/Modules/_sre/sre.c +++ b/Modules/_sre/sre.c @@ -2811,6 +2811,8 @@ scanner_traverse(PyObject *op, visitproc visit, void *arg) ScannerObject *self = _ScannerObject_CAST(op); Py_VISIT(Py_TYPE(self)); Py_VISIT(self->pattern); + Py_VISIT(self->state.string); + Py_VISIT(self->state.buffer.obj); return 0; } @@ -2818,7 +2820,10 @@ static int scanner_clear(PyObject *op) { ScannerObject *self = _ScannerObject_CAST(op); + self->state.start = NULL; Py_CLEAR(self->pattern); + Py_CLEAR(self->state.string); + PyBuffer_Release(&self->state.buffer); return 0; } @@ -2828,8 +2833,8 @@ scanner_dealloc(PyObject *self) PyTypeObject *tp = Py_TYPE(self); PyObject_GC_UnTrack(self); ScannerObject *scanner = _ScannerObject_CAST(self); - state_fini(&scanner->state); (void)scanner_clear(self); + state_fini(&scanner->state); tp->tp_free(self); Py_DECREF(tp); } _______________________________________________ Python-checkins mailing list -- [email protected] To unsubscribe send an email to [email protected] https://mail.python.org/mailman3//lists/python-checkins.python.org Member address: [email protected]
