@@ -1622,9 +1622,8 @@ def testfunc(n):
16221622 self .assertEqual (uops .count ("_PUSH_FRAME" ), 2 )
16231623 # Type version propagation: one guard covers both method lookups
16241624 self .assertEqual (uops .count ("_GUARD_TYPE_VERSION" ), 1 )
1625- # Function checks eliminated (type info resolves the callable)
1626- self .assertNotIn ("_CHECK_FUNCTION_VERSION" , uops )
1627- self .assertNotIn ("_CHECK_FUNCTION_EXACT_ARGS" , uops )
1625+ # Function checks cannot be eliminated for safety reasons.
1626+ self .assertIn ("_CHECK_FUNCTION_VERSION" , uops )
16281627
16291628 def test_method_chain_guard_elimination (self ):
16301629 """
@@ -1669,10 +1668,7 @@ def testfunc(n):
16691668 self .assertIsNotNone (ex )
16701669 uops = get_opnames (ex )
16711670 self .assertIn ("_PUSH_FRAME" , uops )
1672- # Both should be not present, as this is a call
1673- # to a simple function with a known function version.
1674- self .assertNotIn ("_CHECK_FUNCTION_VERSION_INLINE" , uops )
1675- self .assertNotIn ("_CHECK_FUNCTION_VERSION" , uops )
1671+ self .assertIn ("_CHECK_FUNCTION_VERSION" , uops )
16761672 # Removed guard
16771673 self .assertNotIn ("_CHECK_FUNCTION_EXACT_ARGS" , uops )
16781674
@@ -5221,6 +5217,27 @@ def g():
52215217 PYTHON_JIT = "1" , PYTHON_JIT_STRESS = "1" )
52225218 self .assertEqual (result [0 ].rc , 0 , result )
52235219
5220+ def test_func_version_guarded_on_change (self ):
5221+ def testfunc (n ):
5222+ for i in range (n ):
5223+ # Only works on functions promoted to constants
5224+ global_identity_code_will_be_modified (i )
5225+
5226+ testfunc (TIER2_THRESHOLD )
5227+
5228+ ex = get_first_executor (testfunc )
5229+ self .assertIsNotNone (ex )
5230+ uops = get_opnames (ex )
5231+ self .assertIn ("_PUSH_FRAME" , uops )
5232+ self .assertIn ("_CHECK_FUNCTION_VERSION" , uops )
5233+
5234+ global_identity_code_will_be_modified .__code__ = (lambda a : 0xdeadead ).__code__
5235+ _testinternalcapi .clear_executor_deletion_list ()
5236+ ex = get_first_executor (testfunc )
5237+ self .assertIsNone (ex )
5238+ # JItted code should've deopted.
5239+ self .assertEqual (global_identity_code_will_be_modified (None ), 0xdeadead )
5240+
52245241 def test_call_super (self ):
52255242 class A :
52265243 def method1 (self ):
@@ -5267,6 +5284,9 @@ def testfunc(n):
52675284def global_identity (x ):
52685285 return x
52695286
5287+ def global_identity_code_will_be_modified (x ):
5288+ return x
5289+
52705290class TestObject :
52715291 def test (self , * args , ** kwargs ):
52725292 return args [0 ]
0 commit comments