import unittest from test.support import threading_helper import cProfile import pstats NTHREADS = 10 INSERT_PER_THREAD = 1000 @threading_helper.requires_working_threading() class TestCProfile(unittest.TestCase): def test_cprofile_racing_list_insert(self): def list_insert(lst): for i in range(INSERT_PER_THREAD): lst.insert(0, i) lst = [] with cProfile.Profile() as pr: threading_helper.run_concurrently( worker_func=list_insert, nthreads=NTHREADS, args=(lst,) ) pr.create_stats() ps = pstats.Stats(pr) stats_profile = ps.get_stats_profile() list_insert_profile = stats_profile.func_profiles[ "" ] # Even though there is no explicit recursive call to insert, # cProfile may record some calls as recursive due to limitations # in its handling of multithreaded programs. This issue is not # directly related to FT Python itself; however, it tends to be # more noticeable when using FT Python. Therefore, consider only # the calls section and disregard the recursive part. list_insert_ncalls = list_insert_profile.ncalls.split("/")[0] self.assertEqual( int(list_insert_ncalls), NTHREADS * INSERT_PER_THREAD ) self.assertEqual(len(lst), NTHREADS * INSERT_PER_THREAD)