@@ -1959,6 +1959,121 @@ def testfunc(n):
1959
1959
self .assertNotIn ("_GUARD_THIRD_NULL" , uops )
1960
1960
self .assertNotIn ("_GUARD_CALLABLE_ISINSTANCE" , uops )
1961
1961
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
+
1962
2077
1963
2078
def global_identity (x ):
1964
2079
return x
0 commit comments