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