@@ -2105,17 +2105,76 @@ def testfunc(n):
21052105 self .assertNotIn ("_TO_BOOL_BOOL" , uops )
21062106 self .assertIn ("_GUARD_IS_TRUE_POP" , uops )
21072107
2108- def test_call_isinstance_tuple_of_classes (self ):
2108+ def test_call_isinstance_tuple_of_classes_is_true (self ):
21092109 def testfunc (n ):
21102110 x = 0
21112111 for _ in range (n ):
2112- # A tuple of classes is currently not optimized,
2113- # so this is only narrowed to bool:
21142112 y = isinstance (42 , (int , str ))
21152113 if y :
21162114 x += 1
21172115 return x
21182116
2117+ res , ex = self ._run_with_optimizer (testfunc , TIER2_THRESHOLD )
2118+ self .assertEqual (res , TIER2_THRESHOLD )
2119+ self .assertIsNotNone (ex )
2120+ uops = get_opnames (ex )
2121+ self .assertNotIn ("_CALL_ISINSTANCE" , uops )
2122+ self .assertNotIn ("_TO_BOOL_BOOL" , uops )
2123+ self .assertNotIn ("_GUARD_IS_TRUE_POP" , uops )
2124+ self .assertIn ("_BUILD_TUPLE" , uops )
2125+ self .assertIn ("_POP_CALL_TWO_LOAD_CONST_INLINE_BORROW" , uops )
2126+
2127+ def test_call_isinstance_tuple_of_classes_is_false (self ):
2128+ def testfunc (n ):
2129+ x = 0
2130+ for _ in range (n ):
2131+ y = isinstance (42 , (bool , str ))
2132+ if not y :
2133+ x += 1
2134+ return x
2135+
2136+ res , ex = self ._run_with_optimizer (testfunc , TIER2_THRESHOLD )
2137+ self .assertEqual (res , TIER2_THRESHOLD )
2138+ self .assertIsNotNone (ex )
2139+ uops = get_opnames (ex )
2140+ self .assertNotIn ("_CALL_ISINSTANCE" , uops )
2141+ self .assertNotIn ("_TO_BOOL_BOOL" , uops )
2142+ self .assertNotIn ("_GUARD_IS_FALSE_POP" , uops )
2143+ self .assertIn ("_BUILD_TUPLE" , uops )
2144+ self .assertIn ("_POP_CALL_TWO_LOAD_CONST_INLINE_BORROW" , uops )
2145+
2146+ def test_call_isinstance_tuple_of_classes_true_unknown (self ):
2147+ def testfunc (n ):
2148+ x = 0
2149+ for _ in range (n ):
2150+ # One of the classes is unknown, but we can still
2151+ # narrow to True
2152+ y = isinstance (42 , (eval ('str' ), int ))
2153+ if y :
2154+ x += 1
2155+ return x
2156+
2157+ res , ex = self ._run_with_optimizer (testfunc , TIER2_THRESHOLD )
2158+ self .assertEqual (res , TIER2_THRESHOLD )
2159+ self .assertIsNotNone (ex )
2160+ uops = get_opnames (ex )
2161+ self .assertNotIn ("_CALL_ISINSTANCE" , uops )
2162+ self .assertNotIn ("_TO_BOOL_BOOL" , uops )
2163+ self .assertNotIn ("_GUARD_IS_TRUE_POP" , uops )
2164+ self .assertIn ("_BUILD_TUPLE" , uops )
2165+ self .assertIn ("_POP_CALL_TWO_LOAD_CONST_INLINE_BORROW" , uops )
2166+
2167+ def test_call_isinstance_tuple_of_classes_unknown_not_narrowed (self ):
2168+ def testfunc (n ):
2169+ x = 0
2170+ for _ in range (n ):
2171+ # One of the classes is unknown, so we can't narrow
2172+ # to True or False, only bool
2173+ y = isinstance (42 , (str , eval ('int' )))
2174+ if y :
2175+ x += 1
2176+ return x
2177+
21192178 res , ex = self ._run_with_optimizer (testfunc , TIER2_THRESHOLD )
21202179 self .assertEqual (res , TIER2_THRESHOLD )
21212180 self .assertIsNotNone (ex )
@@ -2124,6 +2183,27 @@ def testfunc(n):
21242183 self .assertNotIn ("_TO_BOOL_BOOL" , uops )
21252184 self .assertIn ("_GUARD_IS_TRUE_POP" , uops )
21262185
2186+ def test_call_isinstance_empty_tuple (self ):
2187+ def testfunc (n ):
2188+ x = 0
2189+ for _ in range (n ):
2190+ y = isinstance (42 , ())
2191+ if not y :
2192+ x += 1
2193+ return x
2194+
2195+ res , ex = self ._run_with_optimizer (testfunc , TIER2_THRESHOLD )
2196+ self .assertEqual (res , TIER2_THRESHOLD )
2197+ self .assertIsNotNone (ex )
2198+ uops = get_opnames (ex )
2199+ self .assertNotIn ("_CALL_ISINSTANCE" , uops )
2200+ self .assertNotIn ("_TO_BOOL_BOOL" , uops )
2201+ self .assertNotIn ("_GUARD_IS_FALSE_POP" , uops )
2202+ self .assertNotIn ("_POP_TOP_LOAD_CONST_INLINE_BORROW" , uops )
2203+ self .assertNotIn ("_POP_CALL_LOAD_CONST_INLINE_BORROW" , uops )
2204+ self .assertNotIn ("_POP_CALL_ONE_LOAD_CONST_INLINE_BORROW" , uops )
2205+ self .assertNotIn ("_POP_CALL_TWO_LOAD_CONST_INLINE_BORROW" , uops )
2206+
21272207 def test_call_isinstance_metaclass (self ):
21282208 class EvenNumberMeta (type ):
21292209 def __instancecheck__ (self , number ):
0 commit comments