@@ -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
@@ -5178,6 +5174,27 @@ def g():
51785174 PYTHON_JIT = "1" , PYTHON_JIT_STRESS = "1" )
51795175 self .assertEqual (result [0 ].rc , 0 , result )
51805176
5177+ def test_func_version_guarded_on_change (self ):
5178+ def testfunc (n ):
5179+ for i in range (n ):
5180+ # Only works on functions promoted to constants
5181+ global_identity_code_will_be_modified (i )
5182+
5183+ testfunc (TIER2_THRESHOLD )
5184+
5185+ ex = get_first_executor (testfunc )
5186+ self .assertIsNotNone (ex )
5187+ uops = get_opnames (ex )
5188+ self .assertIn ("_PUSH_FRAME" , uops )
5189+ self .assertIn ("_CHECK_FUNCTION_VERSION" , uops )
5190+
5191+ global_identity_code_will_be_modified .__code__ = (lambda a : 0xdeadead ).__code__
5192+ _testinternalcapi .clear_executor_deletion_list ()
5193+ ex = get_first_executor (testfunc )
5194+ self .assertIsNone (ex )
5195+ # JItted code should've deopted.
5196+ self .assertEqual (global_identity_code_will_be_modified (None ), 0xdeadead )
5197+
51815198 def test_call_super (self ):
51825199 class A :
51835200 def method1 (self ):
@@ -5224,6 +5241,9 @@ def testfunc(n):
52245241def global_identity (x ):
52255242 return x
52265243
5244+ def global_identity_code_will_be_modified (x ):
5245+ return x
5246+
52275247class TestObject :
52285248 def test (self , * args , ** kwargs ):
52295249 return args [0 ]
0 commit comments