From 32768cb819c1e31efa6696ce508a033ddf0af96d Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 13 Oct 2026 22:40:57 +0200 Subject: [PATCH 1/2] gh-157649: Use more warmups in test_cext to check for refleaks Use 3 warmups instead of 1 before checking for reference leaks. Also, always call gc.collect() before reading sys.gettotalrefcount(). --- Lib/test/test_cext/runtests.py | 42 ++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/Lib/test/test_cext/runtests.py b/Lib/test/test_cext/runtests.py index e8288ee5e11e44b..a080db60b6c11f4 100644 --- a/Lib/test/test_cext/runtests.py +++ b/Lib/test/test_cext/runtests.py @@ -19,6 +19,32 @@ def run_tests(testmod, verbose=True): print(flush=True) +def run_refleak_tests(testmod): + # Run tests and check for reference leaks + warmups = 3 + runs = 3 + repcount = warmups + runs + refcount = array.array('q', [0] * repcount) + rep_range = tuple(range(repcount)) + + for i in rep_range: + print(f"Run #{i + 1}", flush=True) + run_tests(testmod) + gc.collect() + refcount[i] = sys.gettotalrefcount() + + first = refcount[0] + for i in rep_range: + refcount[i] -= first + + deltas = list(refcount[warmups:]) + if all(delta >= 1 for delta in deltas): + print(f'ERROR: Tests leaked {deltas} references') + sys.exit(1) + elif any(deltas): + print(f'WARNING: Tests leaked {deltas} references (this is fine)') + + def main(): if len(sys.argv) < 2: print("usage: python runtests.py TEST_MODULE_NAME") @@ -45,21 +71,7 @@ def main(): print() if hasattr(sys, 'gettotalrefcount'): - # First run to warm up Python. For example, test_datetime() imports - # the datetime module. - run_tests(testmod, verbose=False) - - refcount = array.array('q', [0, 0]) - gc.collect() - - # Check for reference leak - refcount[0] = sys.gettotalrefcount() - run_tests(testmod) - refcount[1] = sys.gettotalrefcount() - - diff = refcount[1] - refcount[0] - if diff >= 1: - raise AssertionError(f'Tests leaked {diff} references') + run_refleak_tests(testmod) else: run_tests(testmod) From f6d0d1be724570c7ee127970e638c61117f2443f Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 13 Oct 2026 22:50:35 +0200 Subject: [PATCH 2/2] Compute differences --- Lib/test/test_cext/runtests.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_cext/runtests.py b/Lib/test/test_cext/runtests.py index a080db60b6c11f4..6700b410b7d7a78 100644 --- a/Lib/test/test_cext/runtests.py +++ b/Lib/test/test_cext/runtests.py @@ -33,9 +33,13 @@ def run_refleak_tests(testmod): gc.collect() refcount[i] = sys.gettotalrefcount() - first = refcount[0] + # Compute differences + previous = None for i in rep_range: - refcount[i] -= first + value = refcount[i] + if previous is not None: + refcount[i] = value - previous + previous = value deltas = list(refcount[warmups:]) if all(delta >= 1 for delta in deltas):