@@ -497,6 +497,10 @@ def __init__(
497497 # Used to track edge case when return is still inside except* if it enters a loop
498498 self .return_stmt_inside_except_star_block : bool = False
499499
500+ self ._str_type : Instance | None = None
501+ self ._function_type : Instance | None = None
502+ self ._object_type : Instance | None = None
503+
500504 # mypyc doesn't properly handle implementing an abstractproperty
501505 # with a regular attribute so we make them properties
502506 @property
@@ -1241,7 +1245,7 @@ def analyze_overloaded_func_def(self, defn: OverloadedFuncDef) -> None:
12411245 # This is a property.
12421246 first_item .func .is_overload = True
12431247 bare_setter_type = self .analyze_property_with_multi_part_definition (defn )
1244- typ = function_type (first_item .func , self .named_type ( "builtins.function" ))
1248+ typ = function_type (first_item .func , self .function_type ( ))
12451249 assert isinstance (typ , CallableType )
12461250 typ .definition = first_item
12471251 types = [typ ]
@@ -1373,7 +1377,7 @@ def analyze_overload_sigs_and_impl(
13731377 item .accept (self )
13741378 # TODO: support decorated overloaded functions properly
13751379 if isinstance (item , Decorator ):
1376- callable = function_type (item .func , self .named_type ( "builtins.function" ))
1380+ callable = function_type (item .func , self .function_type ( ))
13771381 assert isinstance (callable , CallableType )
13781382 callable .definition = item
13791383 if not any (refers_to_fullname (dec , OVERLOAD_NAMES ) for dec in item .decorators ):
@@ -1536,9 +1540,7 @@ def analyze_property_with_multi_part_definition(
15361540 if first_node .name == "setter" :
15371541 # The first item represents the entire property.
15381542 first_item .var .is_settable_property = True
1539- setter_func_type = function_type (
1540- item .func , self .named_type ("builtins.function" )
1541- )
1543+ setter_func_type = function_type (item .func , self .function_type ())
15421544 assert isinstance (setter_func_type , CallableType )
15431545 bare_setter_type = setter_func_type
15441546 defn .setter_index = i + 1
@@ -6630,10 +6632,19 @@ def lookup_fully_qualified_or_none(self, fullname: str) -> SymbolTableNode | Non
66306632 return result
66316633
66326634 def object_type (self ) -> Instance :
6633- return self .named_type ("builtins.object" )
6635+ if self ._object_type is None :
6636+ self ._object_type = self .named_type ("builtins.object" )
6637+ return self ._object_type
66346638
66356639 def str_type (self ) -> Instance :
6636- return self .named_type ("builtins.str" )
6640+ if self ._str_type is None :
6641+ self ._str_type = self .named_type ("builtins.str" )
6642+ return self ._str_type
6643+
6644+ def function_type (self ) -> Instance :
6645+ if self ._function_type is None :
6646+ self ._function_type = self .named_type ("builtins.function" )
6647+ return self ._function_type
66376648
66386649 def named_type (self , fullname : str , args : list [Type ] | None = None ) -> Instance :
66396650 sym = self .lookup_fully_qualified (fullname )
0 commit comments