@@ -105,10 +105,7 @@ def test_empty(self):
105105class ArrayReconstructorTest (unittest .TestCase ):
106106
107107 def setUp (self ):
108- if (not support .Py_GIL_DISABLED or
109- any ('"parallel_threads": null' in a for a in sys .argv ) or
110- all ('parallel_threads' not in a for a in sys .argv )):
111- self .enterContext (warnings .catch_warnings ())
108+ self .enterContext (warnings .catch_warnings ())
112109 warnings .filterwarnings (
113110 "ignore" ,
114111 message = "The 'u' type code is deprecated and "
@@ -224,10 +221,7 @@ class BaseTest:
224221 # minitemsize: the minimum guaranteed itemsize
225222
226223 def setUp (self ):
227- if (not support .Py_GIL_DISABLED or
228- any ('"parallel_threads": null' in a for a in sys .argv ) or
229- all ('parallel_threads' not in a for a in sys .argv )):
230- self .enterContext (warnings .catch_warnings ())
224+ self .enterContext (warnings .catch_warnings ())
231225 warnings .filterwarnings (
232226 "ignore" ,
233227 message = "The 'u' type code is deprecated and "
@@ -1696,6 +1690,29 @@ class FreeThreadingTest(unittest.TestCase):
16961690 # Non-deterministic, but at least one of these things will fail if
16971691 # array module is not free-thread safe.
16981692
1693+ def setUp (self ):
1694+ self .enterContext (warnings .catch_warnings ())
1695+ warnings .filterwarnings (
1696+ "ignore" ,
1697+ message = "The 'u' type code is deprecated and "
1698+ "will be removed in Python 3.16" ,
1699+ category = DeprecationWarning )
1700+
1701+ def check (self , funcs , a = None , * args ):
1702+ if a is None :
1703+ a = array .array ('i' , [1 ])
1704+
1705+ barrier = threading .Barrier (len (funcs ))
1706+ threads = []
1707+
1708+ for func in funcs :
1709+ thread = threading .Thread (target = func , args = (barrier , a , * args ))
1710+
1711+ threads .append (thread )
1712+
1713+ with threading_helper .start_threads (threads ):
1714+ pass
1715+
16991716 @unittest .skipUnless (support .Py_GIL_DISABLED , 'this test can only possibly fail with GIL disabled' )
17001717 @threading_helper .reap_threads
17011718 @threading_helper .requires_working_threading ()
@@ -1889,67 +1906,81 @@ def iter_reduce(b, a, it):
18891906 c = it .__reduce__ ()
18901907 assert not c [1 ] or 0xdd not in c [1 ][0 ]
18911908
1892- def check (funcs , a = None , * args ):
1893- if a is None :
1894- a = array .array ('i' , [1 ])
1895-
1896- barrier = threading .Barrier (len (funcs ))
1897- threads = []
1898-
1899- for func in funcs :
1900- thread = threading .Thread (target = func , args = (barrier , a , * args ))
1901-
1902- threads .append (thread )
1903-
1904- with threading_helper .start_threads (threads ):
1905- pass
1906-
1907- check ([pop1 ] * 10 )
1908- check ([pop1 ] + [subscr0 ] * 10 )
1909- check ([append1 ] * 10 )
1910- check ([insert1 ] * 10 )
1911- check ([pop1 ] + [index1 ] * 10 )
1912- check ([pop1 ] + [contains1 ] * 10 )
1913- check ([insert1 ] + [repeat2 ] * 10 )
1914- check ([pop1 ] + [repr1 ] * 10 )
1915- check ([inplace_repeat2 ] * 10 )
1916- check ([byteswap ] * 10 )
1917- check ([insert1 ] + [clear ] * 10 )
1918- check ([pop1 ] + [count1 ] * 10 )
1919- check ([remove1 ] * 10 )
1920- check ([clear ] + [copy ] * 10 , array .array ('B' , b'0' * 0x400000 ))
1921- check ([pop1 ] + [reduce_ex2 ] * 10 )
1922- check ([clear ] + [reduce_ex3 ] * 10 , array .array ('B' , b'0' * 0x400000 ))
1923- check ([pop1 ] + [tobytes ] * 10 )
1924- check ([pop1 ] + [tolist ] * 10 )
1925- check ([clear , tounicode ] * 10 , array .array ('w' , 'a' * 10000 ))
1926- check ([clear , tofile ] * 10 , array .array ('w' , 'a' * 10000 ))
1927- check ([clear ] + [extend ] * 10 )
1928- check ([clear ] + [inplace_concat ] * 10 )
1929- check ([clear ] + [concat ] * 10 , array .array ('w' , 'a' * 10000 ))
1930- check ([fromunicode ] * 10 , array .array ('w' , 'a' ))
1931- check ([frombytes ] * 10 )
1932- check ([fromlist ] * 10 )
1933- check ([clear ] + [richcmplhs ] * 10 , array .array ('i' , [1 ]* 10000 ))
1934- check ([clear ] + [richcmprhs ] * 10 , array .array ('i' , [1 ]* 10000 ))
1935- check ([clear , ass0 ] * 10 , array .array ('i' , [1 ]* 10000 )) # to test array_ass_item must disable Py_mp_ass_subscript
1936- check ([clear ] + [new ] * 10 , array .array ('w' , 'a' * 10000 ))
1937- check ([clear ] + [repr_ ] * 10 , array .array ('B' , b'0' * 0x40000 ))
1938- check ([clear ] + [repr_ ] * 10 , array .array ('B' , b'0' * 0x40000 ))
1939- check ([clear ] + [irepeat ] * 10 , array .array ('B' , b'0' * 0x40000 ))
1940- check ([clear ] + [iter_reduce ] * 10 , a := array .array ('B' , b'0' * 0x400 ), iter (a ))
1909+ self .check ([pop1 ] * 10 )
1910+ self .check ([pop1 ] + [subscr0 ] * 10 )
1911+ self .check ([append1 ] * 10 )
1912+ self .check ([insert1 ] * 10 )
1913+ self .check ([pop1 ] + [index1 ] * 10 )
1914+ self .check ([pop1 ] + [contains1 ] * 10 )
1915+ self .check ([insert1 ] + [repeat2 ] * 10 )
1916+ self .check ([pop1 ] + [repr1 ] * 10 )
1917+ self .check ([inplace_repeat2 ] * 10 )
1918+ self .check ([byteswap ] * 10 )
1919+ self .check ([insert1 ] + [clear ] * 10 )
1920+ self .check ([pop1 ] + [count1 ] * 10 )
1921+ self .check ([remove1 ] * 10 )
1922+ self .check ([clear ] + [copy ] * 10 , array .array ('B' , b'0' * 0x400000 ))
1923+ self .check ([pop1 ] + [reduce_ex2 ] * 10 )
1924+ self .check ([clear ] + [reduce_ex3 ] * 10 , array .array ('B' , b'0' * 0x400000 ))
1925+ self .check ([pop1 ] + [tobytes ] * 10 )
1926+ self .check ([pop1 ] + [tolist ] * 10 )
1927+ self .check ([clear , tounicode ] * 10 , array .array ('w' , 'a' * 10000 ))
1928+ self .check ([clear , tofile ] * 10 , array .array ('w' , 'a' * 10000 ))
1929+ self .check ([clear ] + [extend ] * 10 )
1930+ self .check ([clear ] + [inplace_concat ] * 10 )
1931+ self .check ([clear ] + [concat ] * 10 , array .array ('w' , 'a' * 10000 ))
1932+ self .check ([fromunicode ] * 10 , array .array ('w' , 'a' ))
1933+ self .check ([frombytes ] * 10 )
1934+ self .check ([fromlist ] * 10 )
1935+ self .check ([clear ] + [richcmplhs ] * 10 , array .array ('i' , [1 ]* 10000 ))
1936+ self .check ([clear ] + [richcmprhs ] * 10 , array .array ('i' , [1 ]* 10000 ))
1937+ self .check ([clear , ass0 ] * 10 , array .array ('i' , [1 ]* 10000 )) # to test array_ass_item must disable Py_mp_ass_subscript
1938+ self .check ([clear ] + [new ] * 10 , array .array ('w' , 'a' * 10000 ))
1939+ self .check ([clear ] + [repr_ ] * 10 , array .array ('B' , b'0' * 0x40000 ))
1940+ self .check ([clear ] + [repr_ ] * 10 , array .array ('B' , b'0' * 0x40000 ))
1941+ self .check ([clear ] + [irepeat ] * 10 , array .array ('B' , b'0' * 0x40000 ))
1942+ self .check ([clear ] + [iter_reduce ] * 10 , a := array .array ('B' , b'0' * 0x400 ), iter (a ))
19411943
19421944 # make sure we handle non-self objects correctly
1943- check ([clear ] + [newi ] * 10 , [2 ] * random .randint (0 , 100 ))
1944- check ([fromlistlclear ] + [fromlistl ] * 10 , array .array ('i' , [1 ]), [2 ] * random .randint (0 , 100 ))
1945- check ([clear2 ] + [concat2 ] * 10 , array .array ('w' , 'a' * 10000 ), array .array ('w' , 'a' * 10000 ))
1946- check ([clear2 ] + [inplace_concat2 ] * 10 , array .array ('w' , 'a' * 10000 ), array .array ('w' , 'a' * 10000 ))
1947- check ([clear2 ] + [extend2 ] * 10 , array .array ('w' , 'a' * 10000 ), array .array ('w' , 'a' * 10000 ))
1948- check ([clear2 ] + [ass_subscr2 ] * 10 , array .array ('w' , 'a' * 10000 ), array .array ('w' , 'a' * 10000 ))
1949- check ([clear2 ] + [frombytes2 ] * 10 , array .array ('w' , 'a' * 10000 ), array .array ('B' , b'a' * 10000 ))
1945+ self . check ([clear ] + [newi ] * 10 , [2 ] * random .randint (0 , 100 ))
1946+ self . check ([fromlistlclear ] + [fromlistl ] * 10 , array .array ('i' , [1 ]), [2 ] * random .randint (0 , 100 ))
1947+ self . check ([clear2 ] + [concat2 ] * 10 , array .array ('w' , 'a' * 10000 ), array .array ('w' , 'a' * 10000 ))
1948+ self . check ([clear2 ] + [inplace_concat2 ] * 10 , array .array ('w' , 'a' * 10000 ), array .array ('w' , 'a' * 10000 ))
1949+ self . check ([clear2 ] + [extend2 ] * 10 , array .array ('w' , 'a' * 10000 ), array .array ('w' , 'a' * 10000 ))
1950+ self . check ([clear2 ] + [ass_subscr2 ] * 10 , array .array ('w' , 'a' * 10000 ), array .array ('w' , 'a' * 10000 ))
1951+ self . check ([clear2 ] + [frombytes2 ] * 10 , array .array ('w' , 'a' * 10000 ), array .array ('B' , b'a' * 10000 ))
19501952
19511953 # iterator stuff
1952- check ([clear ] + [iter_next ] * 10 , a := array .array ('i' , [1 ] * 10 ), iter (a ))
1954+ self .check ([clear ] + [iter_next ] * 10 , a := array .array ('i' , [1 ] * 10 ), iter (a ))
1955+
1956+ @unittest .skipUnless (support .check_sanitizer (thread = True ), 'meant for tsan' )
1957+ def test_free_threading_tsan (self ):
1958+ def copy_back_and_forth (b , a , count ):
1959+ b .wait ()
1960+ for _ in range (count ):
1961+ a [0 ] = a [1 ]
1962+ a [1 ] = a [0 ]
1963+
1964+ def extend_range (b , a , count ):
1965+ b .wait ()
1966+ for _ in range (count ):
1967+ a .extend (range (10 ))
1968+
1969+ def append_and_pop (b , a , count ):
1970+ b .wait ()
1971+ for _ in range (count ):
1972+ a .append (1 )
1973+ a .pop ()
1974+
1975+ for tc in typecodes :
1976+ if tc in 'uw' :
1977+ a = array .array (tc , 'ab' )
1978+ else :
1979+ a = array .array (tc , [0 , 1 ])
1980+
1981+ self .check ([copy_back_and_forth ] * 10 , a , 100 )
1982+ self .check ([append_and_pop ] * 10 , a , 100 )
1983+ self .check ([copy_back_and_forth ] * 10 + [extend_range ], a , 10 )
19531984
19541985
19551986if __name__ == "__main__" :
0 commit comments