@@ -35,91 +35,6 @@ def clear_executors(func):
3535 func .__code__ = func .__code__ .replace ()
3636
3737
38- @requires_specialization
39- @unittest .skipIf (Py_GIL_DISABLED , "optimizer not yet supported in free-threaded builds" )
40- @unittest .skipUnless (hasattr (_testinternalcapi , "get_optimizer" ) and
41- hasattr (_testinternalcapi , "new_counter_optimizer" ),
42- "Requires optimizer infrastructure" )
43- class TestOptimizerAPI (unittest .TestCase ):
44-
45- def test_new_counter_optimizer_dealloc (self ):
46- # See gh-108727
47- def f ():
48- _testinternalcapi .new_counter_optimizer ()
49-
50- f ()
51-
52- def test_get_set_optimizer (self ):
53- old = _testinternalcapi .get_optimizer ()
54- opt = _testinternalcapi .new_counter_optimizer ()
55- try :
56- _testinternalcapi .set_optimizer (opt )
57- self .assertEqual (_testinternalcapi .get_optimizer (), opt )
58- _testinternalcapi .set_optimizer (None )
59- self .assertEqual (_testinternalcapi .get_optimizer (), None )
60- finally :
61- _testinternalcapi .set_optimizer (old )
62-
63-
64- def test_counter_optimizer (self ):
65- # Generate a new function at each call
66- ns = {}
67- exec (textwrap .dedent (f"""
68- def loop():
69- for _ in range({ TIER2_THRESHOLD + 1000 } ):
70- pass
71- """ ), ns , ns )
72- loop = ns ['loop' ]
73-
74- for repeat in range (5 ):
75- opt = _testinternalcapi .new_counter_optimizer ()
76- with temporary_optimizer (opt ):
77- self .assertEqual (opt .get_count (), 0 )
78- with clear_executors (loop ):
79- loop ()
80- self .assertEqual (opt .get_count (), 1001 )
81-
82- def test_long_loop (self ):
83- "Check that we aren't confused by EXTENDED_ARG"
84-
85- # Generate a new function at each call
86- ns = {}
87- exec (textwrap .dedent (f"""
88- def nop():
89- pass
90-
91- def long_loop():
92- for _ in range({ TIER2_THRESHOLD + 20 } ):
93- nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop();
94- nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop();
95- nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop();
96- nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop();
97- nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop();
98- nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop();
99- nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop();
100- """ ), ns , ns )
101- long_loop = ns ['long_loop' ]
102-
103- opt = _testinternalcapi .new_counter_optimizer ()
104- with temporary_optimizer (opt ):
105- self .assertEqual (opt .get_count (), 0 )
106- long_loop ()
107- self .assertEqual (opt .get_count (), 21 ) # Need iterations to warm up
108-
109- def test_code_restore_for_ENTER_EXECUTOR (self ):
110- def testfunc (x ):
111- i = 0
112- while i < x :
113- i += 1
114-
115- opt = _testinternalcapi .new_counter_optimizer ()
116- with temporary_optimizer (opt ):
117- testfunc (1000 )
118- code , replace_code = testfunc .__code__ , testfunc .__code__ .replace ()
119- self .assertEqual (code , replace_code )
120- self .assertEqual (hash (code ), hash (replace_code ))
121-
122-
12338def get_first_executor (func ):
12439 code = func .__code__
12540 co_code = code .co_code
@@ -140,89 +55,6 @@ def get_opnames(ex):
14055 return list (iter_opnames (ex ))
14156
14257
143- @requires_specialization
144- @unittest .skipIf (Py_GIL_DISABLED , "optimizer not yet supported in free-threaded builds" )
145- @unittest .skipUnless (hasattr (_testinternalcapi , "get_optimizer" ) and
146- hasattr (_testinternalcapi , "new_counter_optimizer" ),
147- "Requires optimizer infrastructure" )
148- class TestExecutorInvalidation (unittest .TestCase ):
149-
150- def setUp (self ):
151- self .old = _testinternalcapi .get_optimizer ()
152- self .opt = _testinternalcapi .new_counter_optimizer ()
153- _testinternalcapi .set_optimizer (self .opt )
154-
155- def tearDown (self ):
156- _testinternalcapi .set_optimizer (self .old )
157-
158- def test_invalidate_object (self ):
159- # Generate a new set of functions at each call
160- ns = {}
161- func_src = "\n " .join (
162- f"""
163- def f{ n } ():
164- for _ in range({ TIER2_THRESHOLD } ):
165- pass
166- """ for n in range (5 )
167- )
168- exec (textwrap .dedent (func_src ), ns , ns )
169- funcs = [ ns [f'f{ n } ' ] for n in range (5 )]
170- objects = [object () for _ in range (5 )]
171-
172- for f in funcs :
173- f ()
174- executors = [get_first_executor (f ) for f in funcs ]
175- # Set things up so each executor depends on the objects
176- # with an equal or lower index.
177- for i , exe in enumerate (executors ):
178- self .assertTrue (exe .is_valid ())
179- for obj in objects [:i + 1 ]:
180- _testinternalcapi .add_executor_dependency (exe , obj )
181- self .assertTrue (exe .is_valid ())
182- # Assert that the correct executors are invalidated
183- # and check that nothing crashes when we invalidate
184- # an executor multiple times.
185- for i in (4 ,3 ,2 ,1 ,0 ):
186- _testinternalcapi .invalidate_executors (objects [i ])
187- for exe in executors [i :]:
188- self .assertFalse (exe .is_valid ())
189- for exe in executors [:i ]:
190- self .assertTrue (exe .is_valid ())
191-
192- def test_uop_optimizer_invalidation (self ):
193- # Generate a new function at each call
194- ns = {}
195- exec (textwrap .dedent (f"""
196- def f():
197- for i in range({ TIER2_THRESHOLD } ):
198- pass
199- """ ), ns , ns )
200- f = ns ['f' ]
201- opt = _testinternalcapi .new_uop_optimizer ()
202- with temporary_optimizer (opt ):
203- f ()
204- exe = get_first_executor (f )
205- self .assertIsNotNone (exe )
206- self .assertTrue (exe .is_valid ())
207- _testinternalcapi .invalidate_executors (f .__code__ )
208- self .assertFalse (exe .is_valid ())
209-
210- def test_sys__clear_internal_caches (self ):
211- def f ():
212- for _ in range (TIER2_THRESHOLD ):
213- pass
214- opt = _testinternalcapi .new_uop_optimizer ()
215- with temporary_optimizer (opt ):
216- f ()
217- exe = get_first_executor (f )
218- self .assertIsNotNone (exe )
219- self .assertTrue (exe .is_valid ())
220- sys ._clear_internal_caches ()
221- self .assertFalse (exe .is_valid ())
222- exe = get_first_executor (f )
223- self .assertIsNone (exe )
224-
225-
22658@requires_specialization
22759@unittest .skipIf (Py_GIL_DISABLED , "optimizer not yet supported in free-threaded builds" )
22860@unittest .skipUnless (hasattr (_testinternalcapi , "get_optimizer" ),
0 commit comments