From 02ce7f6a1de5f8165b88d65e52ca1c8c1b2a0987 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 6 Oct 2026 22:27:38 +0200 Subject: [PATCH] Fix @reap_threads usage in test_free_threading.test_json Use the decorator on test methods, not on the whole class. Previously, test_json ran no tests: $ ./python -m test -v test_free_threading.test_json -v ... Ran 0 tests in 0.000s NO TESTS RAN Add also a check in @reap_threads to detect misuse (on a class). --- Lib/test/support/threading_helper.py | 6 ++++++ Lib/test/test_free_threading/test_json.py | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Lib/test/support/threading_helper.py b/Lib/test/support/threading_helper.py index cf87233f0e2e93..31be31ac9a9dad 100644 --- a/Lib/test/support/threading_helper.py +++ b/Lib/test/support/threading_helper.py @@ -1,6 +1,7 @@ import _thread import contextlib import functools +import inspect import sys import threading import time @@ -59,6 +60,11 @@ def reap_threads(func): """Use this function when threads are being used. This will ensure that the threads are cleaned up even when the test fails. """ + + if inspect.isclass(func): + # It should be used on each test method, not on the whole class + raise ValueError("@reap_threads is not compatible with classes") + @functools.wraps(func) def decorator(*args): key = threading_setup() diff --git a/Lib/test/test_free_threading/test_json.py b/Lib/test/test_free_threading/test_json.py index 010eb322a15b84..7e3adcf0e81ae2 100644 --- a/Lib/test/test_free_threading/test_json.py +++ b/Lib/test/test_free_threading/test_json.py @@ -29,12 +29,12 @@ def items(self): return self.mapping -@threading_helper.reap_threads @threading_helper.requires_working_threading() class TestJsonEncoding(CTest): # Test encoding json with concurrent threads modifying the data cannot # corrupt the interpreter + @threading_helper.reap_threads def test_json_mutating_list(self): def worker(barrier, data, index): barrier.wait() @@ -48,6 +48,7 @@ def worker(barrier, data, index): data = [[], []] encode_json_helper(self.json, worker, data) + @threading_helper.reap_threads def test_json_mutating_exact_dict(self): def worker(barrier, data, index): barrier.wait() @@ -65,6 +66,7 @@ def worker(barrier, data, index): data = [{}, {}] encode_json_helper(self.json, worker, data) + @threading_helper.reap_threads def test_json_mutating_mapping(self): def worker(barrier, data, index): barrier.wait()