@@ -580,6 +580,9 @@ def testfunction_kw(self, *, kw):
580580 return self
581581
582582
583+ QUICKENING_WARMUP_DELAY = 8
584+
585+
583586class TestPEP590 (unittest .TestCase ):
584587
585588 def test_method_descriptor_flag (self ):
@@ -760,6 +763,54 @@ def __call__(self, *args):
760763 self .assertEqual (expected , meth (* args1 , ** kwargs ))
761764 self .assertEqual (expected , wrapped (* args , ** kwargs ))
762765
766+ def test_setvectorcall (self ):
767+ from _testcapi import function_setvectorcall
768+ def f (num ): return num + 1
769+ assert_equal = self .assertEqual
770+ num = 10
771+ assert_equal (11 , f (num ))
772+ function_setvectorcall (f )
773+ # make sure specializer is triggered by running > 50 times
774+ for _ in range (10 * QUICKENING_WARMUP_DELAY ):
775+ assert_equal ("overridden" , f (num ))
776+
777+ def test_setvectorcall_load_attr_specialization_skip (self ):
778+ from _testcapi import function_setvectorcall
779+
780+ class X :
781+ def __getattribute__ (self , attr ):
782+ return attr
783+
784+ assert_equal = self .assertEqual
785+ x = X ()
786+ assert_equal ("a" , x .a )
787+ function_setvectorcall (X .__getattribute__ )
788+ # make sure specialization doesn't trigger
789+ # when vectorcall is overridden
790+ for _ in range (QUICKENING_WARMUP_DELAY ):
791+ assert_equal ("overridden" , x .a )
792+
793+ def test_setvectorcall_load_attr_specialization_deopt (self ):
794+ from _testcapi import function_setvectorcall
795+
796+ class X :
797+ def __getattribute__ (self , attr ):
798+ return attr
799+
800+ def get_a (x ):
801+ return x .a
802+
803+ assert_equal = self .assertEqual
804+ x = X ()
805+ # trigger LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN specialization
806+ for _ in range (QUICKENING_WARMUP_DELAY ):
807+ assert_equal ("a" , get_a (x ))
808+ function_setvectorcall (X .__getattribute__ )
809+ # make sure specialized LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN
810+ # gets deopted due to overridden vectorcall
811+ for _ in range (QUICKENING_WARMUP_DELAY ):
812+ assert_equal ("overridden" , get_a (x ))
813+
763814 @requires_limited_api
764815 def test_vectorcall_limited (self ):
765816 from _testcapi import pyobject_vectorcall
0 commit comments