From ae1b324fcbf18c2f1ff24b26f464b04f6f0703b2 Mon Sep 17 00:00:00 2001 From: sijun-yang Date: Thu, 24 Sep 2026 21:38:33 +0900 Subject: [PATCH 1/5] Fix reference cycles in re scanners --- Lib/test/test_re.py | 22 ++++++++++++++++++++++ Modules/_sre/sre.c | 2 ++ 2 files changed, 24 insertions(+) diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 8e7611344b9150d..3fdb8396c1d976e 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 @@ -1939,6 +1940,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/Modules/_sre/sre.c b/Modules/_sre/sre.c index 031e972aeba0312..bed862d8a942799 100644 --- a/Modules/_sre/sre.c +++ b/Modules/_sre/sre.c @@ -3017,6 +3017,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; } From 0cf3a201f0108564d7d9a79339733088fff9612b Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Thu, 24 Sep 2026 14:59:10 +0000 Subject: [PATCH 2/5] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2026-09-24-14-59-08.gh-issue-158095.lcKOT4.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2026-09-24-14-59-08.gh-issue-158095.lcKOT4.rst 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..68f7b06a9b1f0cf --- /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. From 60db32d45e963a32fdb234e23442b2a2e32c4498 Mon Sep 17 00:00:00 2001 From: sijun-yang Date: Fri, 25 Sep 2026 00:11:44 +0900 Subject: [PATCH 3/5] gh-158095: Normalize NEWS line endings --- .../next/Library/2026-09-24-14-59-08.gh-issue-158095.lcKOT4.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 68f7b06a9b1f0cf..4fe92b8c8097d85 100644 --- 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 @@ -1,2 +1,2 @@ -Fix a memory leak in :func:`re.finditer` and regular expression scanners when +Fix a memory leak in :func:`re.finditer` and regular expression scanners when their input participates in a reference cycle. From 2982673b235208005fbf504edffee8512b59b242 Mon Sep 17 00:00:00 2001 From: sijun-yang Date: Fri, 25 Sep 2026 23:39:55 +0900 Subject: [PATCH 4/5] gh-158095: Clear input references in re scanners --- Modules/_sre/sre.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Modules/_sre/sre.c b/Modules/_sre/sre.c index bed862d8a942799..d094c59370d024b 100644 --- a/Modules/_sre/sre.c +++ b/Modules/_sre/sre.c @@ -3026,7 +3026,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; } @@ -3036,8 +3039,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); } From 9e7d19e32f85c9510fdfdaf3f8bbe4236d4ae276 Mon Sep 17 00:00:00 2001 From: sijun-yang Date: Sat, 26 Sep 2026 02:44:31 +0900 Subject: [PATCH 5/5] ci: rerun checks Assisted-by: Codex:GPT-6