@@ -2695,6 +2695,82 @@ class D(PNonCall): ...
2695
2695
with self .assertRaises (TypeError ):
2696
2696
issubclass (D , PNonCall )
2697
2697
2698
+ def test_no_weird_caching_with_issubclass_after_isinstance (self ):
2699
+ @runtime_checkable
2700
+ class Spam (Protocol ):
2701
+ x : int
2702
+
2703
+ class Eggs :
2704
+ def __init__ (self ) -> None :
2705
+ self .x = 42
2706
+
2707
+ self .assertIsInstance (Eggs (), Spam )
2708
+
2709
+ # gh-104555: If we didn't override ABCMeta.__subclasscheck__ in _ProtocolMeta,
2710
+ # TypeError wouldn't be raised here,
2711
+ # as the cached result of the isinstance() check immediately above
2712
+ # would mean the issubclass() call would short-circuit
2713
+ # before we got to the "raise TypeError" line
2714
+ with self .assertRaises (TypeError ):
2715
+ issubclass (Eggs , Spam )
2716
+
2717
+ def test_no_weird_caching_with_issubclass_after_isinstance_2 (self ):
2718
+ @runtime_checkable
2719
+ class Spam (Protocol ):
2720
+ x : int
2721
+
2722
+ class Eggs : ...
2723
+
2724
+ self .assertNotIsInstance (Eggs (), Spam )
2725
+
2726
+ # gh-104555: If we didn't override ABCMeta.__subclasscheck__ in _ProtocolMeta,
2727
+ # TypeError wouldn't be raised here,
2728
+ # as the cached result of the isinstance() check immediately above
2729
+ # would mean the issubclass() call would short-circuit
2730
+ # before we got to the "raise TypeError" line
2731
+ with self .assertRaises (TypeError ):
2732
+ issubclass (Eggs , Spam )
2733
+
2734
+ def test_no_weird_caching_with_issubclass_after_isinstance_3 (self ):
2735
+ @runtime_checkable
2736
+ class Spam (Protocol ):
2737
+ x : int
2738
+
2739
+ class Eggs :
2740
+ def __getattr__ (self , attr ):
2741
+ if attr == "x" :
2742
+ return 42
2743
+ raise AttributeError (attr )
2744
+
2745
+ self .assertNotIsInstance (Eggs (), Spam )
2746
+
2747
+ # gh-104555: If we didn't override ABCMeta.__subclasscheck__ in _ProtocolMeta,
2748
+ # TypeError wouldn't be raised here,
2749
+ # as the cached result of the isinstance() check immediately above
2750
+ # would mean the issubclass() call would short-circuit
2751
+ # before we got to the "raise TypeError" line
2752
+ with self .assertRaises (TypeError ):
2753
+ issubclass (Eggs , Spam )
2754
+
2755
+ def test_no_weird_caching_with_issubclass_after_isinstance_pep695 (self ):
2756
+ @runtime_checkable
2757
+ class Spam [T ](Protocol ):
2758
+ x : T
2759
+
2760
+ class Eggs [T ]:
2761
+ def __init__ (self , x : T ) -> None :
2762
+ self .x = x
2763
+
2764
+ self .assertIsInstance (Eggs (42 ), Spam )
2765
+
2766
+ # gh-104555: If we didn't override ABCMeta.__subclasscheck__ in _ProtocolMeta,
2767
+ # TypeError wouldn't be raised here,
2768
+ # as the cached result of the isinstance() check immediately above
2769
+ # would mean the issubclass() call would short-circuit
2770
+ # before we got to the "raise TypeError" line
2771
+ with self .assertRaises (TypeError ):
2772
+ issubclass (Eggs , Spam )
2773
+
2698
2774
def test_protocols_isinstance (self ):
2699
2775
T = TypeVar ('T' )
2700
2776
0 commit comments