@@ -105,24 +105,37 @@ def test_multi_acquire_release_cross_module():
105105 assert len (internals_ids ) == 2 if bits % 8 else 1
106106
107107
108- def _python_to_cpp_to_python ():
109- test_callback_py_obj ()
110- test_callback_std_func ()
111- test_callback_virtual_func ()
112- test_callback_pure_virtual_func ()
113- test_cross_module_gil_released ()
114- test_cross_module_gil_acquired ()
115- test_cross_module_gil_inner_custom_released ()
116- test_cross_module_gil_inner_custom_acquired ()
117- test_cross_module_gil_inner_pybind11_released ()
118- test_cross_module_gil_inner_pybind11_acquired ()
119- test_cross_module_gil_nested_custom_released ()
120- test_cross_module_gil_nested_custom_acquired ()
121- test_cross_module_gil_nested_pybind11_released ()
122- test_cross_module_gil_nested_pybind11_acquired ()
123- test_release_acquire ()
124- test_nested_acquire ()
125- test_multi_acquire_release_cross_module ()
108+ # Intentionally putting human review in the loop here, to guard against accidents.
109+ VARS_BEFORE_ALL_BASIC_TESTS = dict (vars ()) # Make a copy of the dict (critical).
110+ ALL_BASIC_TESTS = (
111+ test_callback_py_obj ,
112+ test_callback_std_func ,
113+ test_callback_virtual_func ,
114+ test_callback_pure_virtual_func ,
115+ test_cross_module_gil_released ,
116+ test_cross_module_gil_acquired ,
117+ test_cross_module_gil_inner_custom_released ,
118+ test_cross_module_gil_inner_custom_acquired ,
119+ test_cross_module_gil_inner_pybind11_released ,
120+ test_cross_module_gil_inner_pybind11_acquired ,
121+ test_cross_module_gil_nested_custom_released ,
122+ test_cross_module_gil_nested_custom_acquired ,
123+ test_cross_module_gil_nested_pybind11_released ,
124+ test_cross_module_gil_nested_pybind11_acquired ,
125+ test_release_acquire ,
126+ test_nested_acquire ,
127+ test_multi_acquire_release_cross_module ,
128+ )
129+
130+
131+ def test_all_basic_tests_completeness ():
132+ num_found = 0
133+ for key , value in VARS_BEFORE_ALL_BASIC_TESTS .items ():
134+ if not key .startswith ("test_" ):
135+ continue
136+ assert value in ALL_BASIC_TESTS
137+ num_found += 1
138+ assert len (ALL_BASIC_TESTS ) == num_found
126139
127140
128141def _run_in_process (target , * args , ** kwargs ):
@@ -139,11 +152,10 @@ def _run_in_process(target, *args, **kwargs):
139152 process .terminate ()
140153
141154
142- def _python_to_cpp_to_python_from_threads (num_threads , parallel = False ):
143- """Calls different C++ functions that come back to Python, from Python threads."""
155+ def _run_in_threads (target , num_threads , parallel ):
144156 threads = []
145157 for _ in range (num_threads ):
146- thread = threading .Thread (target = _python_to_cpp_to_python )
158+ thread = threading .Thread (target = target )
147159 thread .daemon = True
148160 thread .start ()
149161 if parallel :
@@ -155,44 +167,46 @@ def _python_to_cpp_to_python_from_threads(num_threads, parallel=False):
155167
156168
157169# TODO: FIXME, sometimes returns -11 (segfault) instead of 0 on macOS Python 3.9
158- def test_python_to_cpp_to_python_from_thread ():
170+ @pytest .mark .parametrize ("test_fn" , ALL_BASIC_TESTS )
171+ def test_run_in_process_one_thread (test_fn ):
159172 """Makes sure there is no GIL deadlock when running in a thread.
160173
161174 It runs in a separate process to be able to stop and assert if it deadlocks.
162175 """
163- assert _run_in_process (_python_to_cpp_to_python_from_threads , 1 ) == 0
176+ assert _run_in_process (_run_in_threads , test_fn , num_threads = 1 , parallel = False ) == 0
164177
165178
166179# TODO: FIXME on macOS Python 3.9
167- def test_python_to_cpp_to_python_from_thread_multiple_parallel ():
180+ @pytest .mark .parametrize ("test_fn" , ALL_BASIC_TESTS )
181+ def test_run_in_process_multiple_threads_parallel (test_fn ):
168182 """Makes sure there is no GIL deadlock when running in a thread multiple times in parallel.
169183
170184 It runs in a separate process to be able to stop and assert if it deadlocks.
171185 """
172- exitcode = _run_in_process (_python_to_cpp_to_python_from_threads , 8 , parallel = True )
186+ exitcode = _run_in_process (_run_in_threads , test_fn , num_threads = 8 , parallel = True )
173187 if exitcode is None and env .PYPY and env .WIN : # Seems to be flaky.
174188 pytest .skip ("Ignoring unexpected exitcode None (PYPY WIN)" )
175189 assert exitcode == 0
176190
177191
178192# TODO: FIXME on macOS Python 3.9
179- def test_python_to_cpp_to_python_from_thread_multiple_sequential ():
193+ @pytest .mark .parametrize ("test_fn" , ALL_BASIC_TESTS )
194+ def test_run_in_process_multiple_threads_sequential (test_fn ):
180195 """Makes sure there is no GIL deadlock when running in a thread multiple times sequentially.
181196
182197 It runs in a separate process to be able to stop and assert if it deadlocks.
183198 """
184- assert (
185- _run_in_process (_python_to_cpp_to_python_from_threads , 8 , parallel = False ) == 0
186- )
199+ assert _run_in_process (_run_in_threads , test_fn , num_threads = 8 , parallel = False ) == 0
187200
188201
189202# TODO: FIXME on macOS Python 3.9
190- def test_python_to_cpp_to_python_from_process ():
203+ @pytest .mark .parametrize ("test_fn" , ALL_BASIC_TESTS )
204+ def test_run_in_process_direct (test_fn ):
191205 """Makes sure there is no GIL deadlock when using processes.
192206
193207 This test is for completion, but it was never an issue.
194208 """
195- exitcode = _run_in_process (_python_to_cpp_to_python )
209+ exitcode = _run_in_process (test_fn )
196210 if exitcode is None and env .PYPY and env .WIN : # Seems to be flaky.
197211 pytest .skip ("Ignoring unexpected exitcode None (PYPY WIN)" )
198212 assert exitcode == 0
0 commit comments