import ctypes import sys import unittest from test.support import threading_helper from test.support.threading_helper import run_concurrently _PyImport_AddModuleRef = ctypes.pythonapi.PyImport_AddModuleRef _PyImport_AddModuleRef.argtypes = (ctypes.c_char_p,) _PyImport_AddModuleRef.restype = ctypes.py_object @threading_helper.requires_working_threading() class TestImportCAPI(unittest.TestCase): def test_pyimport_addmoduleref_thread_safe(self): # gh-137422: Concurrent calls to PyImport_AddModuleRef with the same # module name must return the same module object. NUM_ITERS = 10 NTHREADS = 4 module_name = f"test_free_threading_addmoduleref_{id(self)}" module_name_bytes = module_name.encode() sys.modules.pop(module_name, None) results = [] def worker(): module = _PyImport_AddModuleRef(module_name_bytes) results.append(module) for _ in range(NUM_ITERS): try: run_concurrently(worker_func=worker, nthreads=NTHREADS) self.assertEqual(len(results), NTHREADS) reference = results[0] for module in results[1:]: self.assertIs(module, reference) self.assertIn(module_name, sys.modules) self.assertIs(sys.modules[module_name], reference) finally: results.clear() sys.modules.pop(module_name, None) if __name__ == "__main__": unittest.main()