1111from collections .abc import Iterable , Sequence
1212from typing import Any , Callable , TypeVar , cast
1313
14+ from mypy .checker_state import checker_state
1415from mypy .copytype import copy_type
1516from mypy .expandtype import expand_type , expand_type_by_instance
1617from mypy .maptype import map_instance_to_supertype
@@ -145,6 +146,15 @@ def type_object_type(info: TypeInfo, named_type: Callable[[str], Instance]) -> P
145146 where ... are argument types for the __init__/__new__ method (without the self
146147 argument). Also, the fallback type will be 'type' instead of 'function'.
147148 """
149+ allow_cache = (
150+ checker_state .type_checker is not None
151+ and checker_state .type_checker .allow_constructor_cache
152+ )
153+
154+ if info .type_object_type is not None :
155+ if allow_cache :
156+ return info .type_object_type
157+ info .type_object_type = None
148158
149159 # We take the type from whichever of __init__ and __new__ is first
150160 # in the MRO, preferring __init__ if there is a tie.
@@ -167,7 +177,15 @@ def type_object_type(info: TypeInfo, named_type: Callable[[str], Instance]) -> P
167177 init_index = info .mro .index (init_method .node .info )
168178 new_index = info .mro .index (new_method .node .info )
169179
170- fallback = info .metaclass_type or named_type ("builtins.type" )
180+ if info .metaclass_type is not None :
181+ fallback = info .metaclass_type
182+ elif checker_state .type_checker :
183+ # Prefer direct call when it is available. It is faster, and,
184+ # unfortunately, some callers provide bogus callback.
185+ fallback = checker_state .type_checker .named_type ("builtins.type" )
186+ else :
187+ fallback = named_type ("builtins.type" )
188+
171189 if init_index < new_index :
172190 method : FuncBase | Decorator = init_method .node
173191 is_new = False
@@ -189,7 +207,10 @@ def type_object_type(info: TypeInfo, named_type: Callable[[str], Instance]) -> P
189207 is_bound = True ,
190208 fallback = named_type ("builtins.function" ),
191209 )
192- return class_callable (sig , info , fallback , None , is_new = False )
210+ result : FunctionLike = class_callable (sig , info , fallback , None , is_new = False )
211+ if allow_cache :
212+ info .type_object_type = result
213+ return result
193214
194215 # Otherwise prefer __init__ in a tie. It isn't clear that this
195216 # is the right thing, but __new__ caused problems with
@@ -199,12 +220,19 @@ def type_object_type(info: TypeInfo, named_type: Callable[[str], Instance]) -> P
199220 # Construct callable type based on signature of __init__. Adjust
200221 # return type and insert type arguments.
201222 if isinstance (method , FuncBase ):
223+ if isinstance (method , OverloadedFuncDef ) and not method .type :
224+ # Do not cache if the type is not ready. Same logic for decorators is
225+ # achieved in early return above because is_valid_constructor() is False.
226+ allow_cache = False
202227 t = function_type (method , fallback )
203228 else :
204229 assert isinstance (method .type , ProperType )
205230 assert isinstance (method .type , FunctionLike ) # is_valid_constructor() ensures this
206231 t = method .type
207- return type_object_type_from_function (t , info , method .info , fallback , is_new )
232+ result = type_object_type_from_function (t , info , method .info , fallback , is_new )
233+ if allow_cache :
234+ info .type_object_type = result
235+ return result
208236
209237
210238def is_valid_constructor (n : SymbolNode | None ) -> bool :
@@ -865,8 +893,8 @@ def function_type(func: FuncBase, fallback: Instance) -> FunctionLike:
865893 if isinstance (func , FuncItem ):
866894 return callable_type (func , fallback )
867895 else :
868- # Broken overloads can have self. type set to None .
869- # TODO: should we instead always set the type in semantic analyzer?
896+ # Either a broken overload, or decorated overload type is not ready .
897+ # TODO: make sure the caller defers if possible.
870898 assert isinstance (func , OverloadedFuncDef )
871899 any_type = AnyType (TypeOfAny .from_error )
872900 dummy = CallableType (
@@ -1254,6 +1282,8 @@ def get_protocol_member(
12541282 if member == "__call__" and class_obj :
12551283 # Special case: class objects always have __call__ that is just the constructor.
12561284
1285+ # TODO: this is wrong, it creates callables that are not recognized as type objects.
1286+ # Long-term, we should probably get rid of this callback argument altogether.
12571287 def named_type (fullname : str ) -> Instance :
12581288 return Instance (left .type .mro [- 1 ], [])
12591289
0 commit comments