33from doctest import DocTestSuite
44from test import support
55from test .support import threading_helper
6+ from test .support .import_helper import import_module
67import weakref
7- import gc
88
99# Modules under test
1010import _thread
1111import threading
1212import _threading_local
1313
1414
15+ threading_helper .requires_working_threading (module = True )
16+
17+
1518class Weak (object ):
1619 pass
1720
@@ -23,7 +26,7 @@ def target(local, weaklist):
2326
2427class BaseLocalTest :
2528
26- @unittest .skip (" TODO: RUSTPYTHON, flaky test" )
29+ @unittest .skip (' TODO: RUSTPYTHON; flaky test' )
2730 def test_local_refs (self ):
2831 self ._local_refs (20 )
2932 self ._local_refs (50 )
@@ -182,8 +185,7 @@ class LocalSubclass(self._local):
182185 """To test that subclasses behave properly."""
183186 self ._test_dict_attribute (LocalSubclass )
184187
185- # TODO: RUSTPYTHON, cycle detection/collection
186- @unittest .expectedFailure
188+ @unittest .expectedFailure # TODO: RUSTPYTHON; cycle detection/collection
187189 def test_cycle_collection (self ):
188190 class X :
189191 pass
@@ -197,35 +199,53 @@ class X:
197199 self .assertIsNone (wr ())
198200
199201
200- class ThreadLocalTest (unittest .TestCase , BaseLocalTest ):
201- _local = _thread ._local
202+ def test_threading_local_clear_race (self ):
203+ # See https://github.com/python/cpython/issues/100892
204+
205+ _testcapi = import_module ('_testcapi' )
206+ _testcapi .call_in_temporary_c_thread (lambda : None , False )
207+
208+ for _ in range (1000 ):
209+ _ = threading .local ()
202210
203- # TODO: RUSTPYTHON, __new__ vs __init__ cooperation
204- @unittest .expectedFailure
205- def test_arguments ():
206- super ().test_arguments ()
211+ _testcapi .join_temporary_c_thread ()
207212
213+ @support .cpython_only
214+ def test_error (self ):
215+ class Loop (self ._local ):
216+ attr = 1
217+
218+ # Trick the "if name == '__dict__':" test of __setattr__()
219+ # to always be true
220+ class NameCompareTrue :
221+ def __eq__ (self , other ):
222+ return True
223+
224+ loop = Loop ()
225+ with self .assertRaisesRegex (AttributeError , 'Loop.*read-only' ):
226+ loop .__setattr__ (NameCompareTrue (), 2 )
227+
228+
229+ class ThreadLocalTest (unittest .TestCase , BaseLocalTest ):
230+ _local = _thread ._local
208231
209232class PyThreadingLocalTest (unittest .TestCase , BaseLocalTest ):
210233 _local = _threading_local .local
211234
212235
213- def test_main ():
214- suite = unittest .TestSuite ()
215- suite .addTest (DocTestSuite ('_threading_local' ))
216- suite .addTest (unittest .makeSuite (ThreadLocalTest ))
217- suite .addTest (unittest .makeSuite (PyThreadingLocalTest ))
236+ def load_tests (loader , tests , pattern ):
237+ tests .addTest (DocTestSuite ('_threading_local' ))
218238
219239 local_orig = _threading_local .local
220240 def setUp (test ):
221241 _threading_local .local = _thread ._local
222242 def tearDown (test ):
223243 _threading_local .local = local_orig
224- suite .addTest (DocTestSuite ('_threading_local' ,
225- setUp = setUp , tearDown = tearDown )
226- )
244+ tests .addTests (DocTestSuite ('_threading_local' ,
245+ setUp = setUp , tearDown = tearDown )
246+ )
247+ return tests
227248
228- support .run_unittest (suite )
229249
230250if __name__ == '__main__' :
231- test_main ()
251+ unittest . main ()
0 commit comments