@@ -1959,6 +1959,121 @@ def testfunc(n):
19591959 self .assertNotIn ("_GUARD_THIRD_NULL" , uops )
19601960 self .assertNotIn ("_GUARD_CALLABLE_ISINSTANCE" , uops )
19611961
1962+ def test_call_isinstance_is_true (self ):
1963+ def testfunc (n ):
1964+ x = 0
1965+ for _ in range (n ):
1966+ y = isinstance (42 , int )
1967+ if y :
1968+ x += 1
1969+ return x
1970+
1971+ res , ex = self ._run_with_optimizer (testfunc , TIER2_THRESHOLD )
1972+ self .assertEqual (res , TIER2_THRESHOLD )
1973+ self .assertIsNotNone (ex )
1974+ uops = get_opnames (ex )
1975+ self .assertIn ("_CALL_ISINSTANCE" , uops )
1976+ self .assertNotIn ("_TO_BOOL_BOOL" , uops )
1977+ self .assertNotIn ("_GUARD_IS_TRUE_POP" , uops )
1978+
1979+ def test_call_isinstance_is_false (self ):
1980+ def testfunc (n ):
1981+ x = 0
1982+ for _ in range (n ):
1983+ y = isinstance (42 , str )
1984+ if not y :
1985+ x += 1
1986+ return x
1987+
1988+ res , ex = self ._run_with_optimizer (testfunc , TIER2_THRESHOLD )
1989+ self .assertEqual (res , TIER2_THRESHOLD )
1990+ self .assertIsNotNone (ex )
1991+ uops = get_opnames (ex )
1992+ self .assertIn ("_CALL_ISINSTANCE" , uops )
1993+ self .assertNotIn ("_TO_BOOL_BOOL" , uops )
1994+ self .assertNotIn ("_GUARD_IS_FALSE_POP" , uops )
1995+
1996+ def test_call_isinstance_subclass (self ):
1997+ def testfunc (n ):
1998+ x = 0
1999+ for _ in range (n ):
2000+ y = isinstance (True , int )
2001+ if y :
2002+ x += 1
2003+ return x
2004+
2005+ res , ex = self ._run_with_optimizer (testfunc , TIER2_THRESHOLD )
2006+ self .assertEqual (res , TIER2_THRESHOLD )
2007+ self .assertIsNotNone (ex )
2008+ uops = get_opnames (ex )
2009+ self .assertIn ("_CALL_ISINSTANCE" , uops )
2010+ self .assertNotIn ("_TO_BOOL_BOOL" , uops )
2011+ self .assertNotIn ("_GUARD_IS_TRUE_POP" , uops )
2012+
2013+ def test_call_isinstance_unknown_object (self ):
2014+ def testfunc (n ):
2015+ x = 0
2016+ for _ in range (n ):
2017+ # The optimizer doesn't know the return type here:
2018+ bar = eval ("42" )
2019+ # This will only narrow to bool:
2020+ y = isinstance (bar , int )
2021+ if y :
2022+ x += 1
2023+ return x
2024+
2025+ res , ex = self ._run_with_optimizer (testfunc , TIER2_THRESHOLD )
2026+ self .assertEqual (res , TIER2_THRESHOLD )
2027+ self .assertIsNotNone (ex )
2028+ uops = get_opnames (ex )
2029+ self .assertIn ("_CALL_ISINSTANCE" , uops )
2030+ self .assertNotIn ("_TO_BOOL_BOOL" , uops )
2031+ self .assertIn ("_GUARD_IS_TRUE_POP" , uops )
2032+
2033+ def test_call_isinstance_tuple_of_classes (self ):
2034+ def testfunc (n ):
2035+ x = 0
2036+ for _ in range (n ):
2037+ # A tuple of classes is currently not optimized,
2038+ # so this is only narrowed to bool:
2039+ y = isinstance (42 , (int , str ))
2040+ if y :
2041+ x += 1
2042+ return x
2043+
2044+ res , ex = self ._run_with_optimizer (testfunc , TIER2_THRESHOLD )
2045+ self .assertEqual (res , TIER2_THRESHOLD )
2046+ self .assertIsNotNone (ex )
2047+ uops = get_opnames (ex )
2048+ self .assertIn ("_CALL_ISINSTANCE" , uops )
2049+ self .assertNotIn ("_TO_BOOL_BOOL" , uops )
2050+ self .assertIn ("_GUARD_IS_TRUE_POP" , uops )
2051+
2052+ def test_call_isinstance_metaclass (self ):
2053+ class EvenNumberMeta (type ):
2054+ def __instancecheck__ (self , number ):
2055+ return number % 2 == 0
2056+
2057+ class EvenNumber (metaclass = EvenNumberMeta ):
2058+ pass
2059+
2060+ def testfunc (n ):
2061+ x = 0
2062+ for _ in range (n ):
2063+ # Only narrowed to bool
2064+ y = isinstance (42 , EvenNumber )
2065+ if y :
2066+ x += 1
2067+ return x
2068+
2069+ res , ex = self ._run_with_optimizer (testfunc , TIER2_THRESHOLD )
2070+ self .assertEqual (res , TIER2_THRESHOLD )
2071+ self .assertIsNotNone (ex )
2072+ uops = get_opnames (ex )
2073+ self .assertIn ("_CALL_ISINSTANCE" , uops )
2074+ self .assertNotIn ("_TO_BOOL_BOOL" , uops )
2075+ self .assertIn ("_GUARD_IS_TRUE_POP" , uops )
2076+
19622077
19632078def global_identity (x ):
19642079 return x
0 commit comments