22
33from __future__ import annotations
44
5- from typing import TYPE_CHECKING , Callable , Sequence , cast
5+ from typing import TYPE_CHECKING , Callable , Optional , Sequence , cast
66
77from mypy import meet , message_registry , subtypes
88from mypy .erasetype import erase_typevars
@@ -776,12 +776,17 @@ def analyze_var(
776776 freeze_all_type_vars (t )
777777 result : Type = t
778778 typ = get_proper_type (typ )
779- if (
780- var .is_initialized_in_class
781- and (not is_instance_var (var ) or mx .is_operator )
782- and isinstance (typ , FunctionLike )
783- and not typ .is_type_obj ()
784- ):
779+
780+ call_type : Optional [ProperType ] = None
781+ if var .is_initialized_in_class and (not is_instance_var (var ) or mx .is_operator ):
782+ if isinstance (typ , FunctionLike ) and not typ .is_type_obj ():
783+ call_type = typ
784+ elif var .is_property :
785+ call_type = get_proper_type (_analyze_member_access ("__call__" , typ , mx ))
786+ else :
787+ call_type = typ
788+
789+ if isinstance (call_type , FunctionLike ) and not call_type .is_type_obj ():
785790 if mx .is_lvalue :
786791 if var .is_property :
787792 if not var .is_settable_property :
@@ -792,7 +797,7 @@ def analyze_var(
792797 if not var .is_staticmethod :
793798 # Class-level function objects and classmethods become bound methods:
794799 # the former to the instance, the latter to the class.
795- functype = typ
800+ functype : FunctionLike = call_type
796801 # Use meet to narrow original_type to the dispatched type.
797802 # For example, assume
798803 # * A.f: Callable[[A1], None] where A1 <: A (maybe A1 == A)
0 commit comments