Skip to content

Commit aaa9a6c

Browse files
committed
Cache common builtins instances
1 parent 04f38f5 commit aaa9a6c

File tree

2 files changed

+43
-7
lines changed

2 files changed

+43
-7
lines changed

mypy/checker.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,12 @@ def __init__(
431431
self._expr_checker = mypy.checkexpr.ExpressionChecker(
432432
self, self.msg, self.plugin, per_line_checking_time_ns
433433
)
434+
435+
self._object_type: Instance | None = None
436+
self._type_type: Instance | None = None
437+
self._str_type: Instance | None = None
438+
self._function_type: Instance | None = None
439+
434440
self.pattern_checker = PatternChecker(self, self.msg, self.plugin, options)
435441
self._unique_id = 0
436442

@@ -7369,6 +7375,25 @@ def named_type(self, name: str) -> Instance:
73697375
73707376
For example, named_type('builtins.object') produces the 'object' type.
73717377
"""
7378+
if name == "builtins.function":
7379+
if self._function_type is None:
7380+
self._function_type = self._named_type(name)
7381+
return self._function_type
7382+
if name == "builtins.object":
7383+
if self._object_type is None:
7384+
self._object_type = self._named_type(name)
7385+
return self._object_type
7386+
if name == "builtins.type":
7387+
if self._type_type is None:
7388+
self._type_type = self._named_type(name)
7389+
return self._type_type
7390+
if name == "builtins.str":
7391+
if self._str_type is None:
7392+
self._str_type = self._named_type(name)
7393+
return self._str_type
7394+
return self._named_type(name)
7395+
7396+
def _named_type(self, name: str) -> Instance:
73727397
# Assume that the name refers to a type.
73737398
sym = self.lookup_qualified(name)
73747399
node = sym.node

mypy/semanal.py

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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._object_type: Instance | None = None
501+
self._str_type: Instance | None = None
502+
self._function_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

Comments
 (0)