@@ -1708,6 +1708,23 @@ def deserialize(cls, data: JsonDict | str) -> Instance:
17081708
17091709 def write (self , data : Buffer ) -> None :
17101710 write_tag (data , INSTANCE )
1711+ if not self .args and not self .last_known_value and not self .extra_attrs :
1712+ type_ref = self .type .fullname
1713+ if type_ref == "builtins.str" :
1714+ write_tag (data , INSTANCE_STR )
1715+ elif type_ref == "builtins.function" :
1716+ write_tag (data , INSTANCE_FUNCTION )
1717+ elif type_ref == "builtins.int" :
1718+ write_tag (data , INSTANCE_INT )
1719+ elif type_ref == "builtins.bool" :
1720+ write_tag (data , INSTANCE_BOOL )
1721+ elif type_ref == "builtins.object" :
1722+ write_tag (data , INSTANCE_OBJECT )
1723+ else :
1724+ write_tag (data , INSTANCE_SIMPLE )
1725+ write_str (data , type_ref )
1726+ return
1727+ write_tag (data , INSTANCE_GENERIC )
17111728 write_str (data , self .type .fullname )
17121729 write_type_list (data , self .args )
17131730 write_type_opt (data , self .last_known_value )
@@ -1719,6 +1736,39 @@ def write(self, data: Buffer) -> None:
17191736
17201737 @classmethod
17211738 def read (cls , data : Buffer ) -> Instance :
1739+ tag = read_tag (data )
1740+ # This is quite verbose, but this is very hot code, so we are not
1741+ # using dictionary lookups here.
1742+ if tag == INSTANCE_STR :
1743+ if instance_cache .str_type is None :
1744+ instance_cache .str_type = Instance (NOT_READY , [])
1745+ instance_cache .str_type .type_ref = "builtins.str"
1746+ return instance_cache .str_type
1747+ if tag == INSTANCE_FUNCTION :
1748+ if instance_cache .function_type is None :
1749+ instance_cache .function_type = Instance (NOT_READY , [])
1750+ instance_cache .function_type .type_ref = "builtins.function"
1751+ return instance_cache .function_type
1752+ if tag == INSTANCE_INT :
1753+ if instance_cache .int_type is None :
1754+ instance_cache .int_type = Instance (NOT_READY , [])
1755+ instance_cache .int_type .type_ref = "builtins.int"
1756+ return instance_cache .int_type
1757+ if tag == INSTANCE_BOOL :
1758+ if instance_cache .bool_type is None :
1759+ instance_cache .bool_type = Instance (NOT_READY , [])
1760+ instance_cache .bool_type .type_ref = "builtins.bool"
1761+ return instance_cache .bool_type
1762+ if tag == INSTANCE_OBJECT :
1763+ if instance_cache .object_type is None :
1764+ instance_cache .object_type = Instance (NOT_READY , [])
1765+ instance_cache .object_type .type_ref = "builtins.object"
1766+ return instance_cache .object_type
1767+ if tag == INSTANCE_SIMPLE :
1768+ inst = Instance (NOT_READY , [])
1769+ inst .type_ref = read_str (data )
1770+ return inst
1771+ assert tag == INSTANCE_GENERIC
17221772 type_ref = read_str (data )
17231773 inst = Instance (NOT_READY , read_type_list (data ))
17241774 inst .type_ref = type_ref
@@ -1769,6 +1819,25 @@ def is_singleton_type(self) -> bool:
17691819 )
17701820
17711821
1822+ class InstanceCache :
1823+ def __init__ (self ) -> None :
1824+ self .str_type : Instance | None = None
1825+ self .function_type : Instance | None = None
1826+ self .int_type : Instance | None = None
1827+ self .bool_type : Instance | None = None
1828+ self .object_type : Instance | None = None
1829+
1830+ def reset (self ) -> None :
1831+ self .str_type = None
1832+ self .function_type = None
1833+ self .int_type = None
1834+ self .bool_type = None
1835+ self .object_type = None
1836+
1837+
1838+ instance_cache : Final = InstanceCache ()
1839+
1840+
17721841class FunctionLike (ProperType ):
17731842 """Abstract base class for function types."""
17741843
@@ -4142,6 +4211,14 @@ def type_vars_as_args(type_vars: Sequence[TypeVarLikeType]) -> tuple[Type, ...]:
41424211TYPE_TYPE : Final [Tag ] = 18
41434212PARAMETERS : Final [Tag ] = 19
41444213
4214+ INSTANCE_STR : Final [Tag ] = 101
4215+ INSTANCE_FUNCTION : Final [Tag ] = 102
4216+ INSTANCE_INT : Final [Tag ] = 103
4217+ INSTANCE_BOOL : Final [Tag ] = 104
4218+ INSTANCE_OBJECT : Final [Tag ] = 105
4219+ INSTANCE_SIMPLE : Final [Tag ] = 106
4220+ INSTANCE_GENERIC : Final [Tag ] = 107
4221+
41454222
41464223def read_type (data : Buffer ) -> Type :
41474224 tag = read_tag (data )
0 commit comments