@@ -541,7 +541,33 @@ def visit_instance(self, template: Instance) -> list[Constraint]:
541
541
template .type .inferring .pop ()
542
542
return res
543
543
if isinstance (actual , CallableType ) and actual .fallback is not None :
544
+ if actual .is_type_obj () and template .type .is_protocol :
545
+ ret_type = get_proper_type (actual .ret_type )
546
+ if isinstance (ret_type , TupleType ):
547
+ ret_type = mypy .typeops .tuple_fallback (ret_type )
548
+ if isinstance (ret_type , Instance ):
549
+ if self .direction == SUBTYPE_OF :
550
+ subtype = template
551
+ else :
552
+ subtype = ret_type
553
+ res .extend (
554
+ self .infer_constraints_from_protocol_members (
555
+ ret_type , template , subtype , template , class_obj = True
556
+ )
557
+ )
544
558
actual = actual .fallback
559
+ if isinstance (actual , TypeType ) and template .type .is_protocol :
560
+ if isinstance (actual .item , Instance ):
561
+ if self .direction == SUBTYPE_OF :
562
+ subtype = template
563
+ else :
564
+ subtype = actual .item
565
+ res .extend (
566
+ self .infer_constraints_from_protocol_members (
567
+ actual .item , template , subtype , template , class_obj = True
568
+ )
569
+ )
570
+
545
571
if isinstance (actual , Overloaded ) and actual .fallback is not None :
546
572
actual = actual .fallback
547
573
if isinstance (actual , TypedDictType ):
@@ -715,6 +741,9 @@ def visit_instance(self, template: Instance) -> list[Constraint]:
715
741
)
716
742
instance .type .inferring .pop ()
717
743
return res
744
+ if res :
745
+ return res
746
+
718
747
if isinstance (actual , AnyType ):
719
748
return self .infer_against_any (template .args , actual )
720
749
if (
@@ -740,7 +769,12 @@ def visit_instance(self, template: Instance) -> list[Constraint]:
740
769
return []
741
770
742
771
def infer_constraints_from_protocol_members (
743
- self , instance : Instance , template : Instance , subtype : Type , protocol : Instance
772
+ self ,
773
+ instance : Instance ,
774
+ template : Instance ,
775
+ subtype : Type ,
776
+ protocol : Instance ,
777
+ class_obj : bool = False ,
744
778
) -> list [Constraint ]:
745
779
"""Infer constraints for situations where either 'template' or 'instance' is a protocol.
746
780
@@ -750,7 +784,7 @@ def infer_constraints_from_protocol_members(
750
784
"""
751
785
res = []
752
786
for member in protocol .type .protocol_members :
753
- inst = mypy .subtypes .find_member (member , instance , subtype )
787
+ inst = mypy .subtypes .find_member (member , instance , subtype , class_obj = class_obj )
754
788
temp = mypy .subtypes .find_member (member , template , subtype )
755
789
if inst is None or temp is None :
756
790
return [] # See #11020
0 commit comments