Skip to content

Commit 5f5871d

Browse files
authored
Micro-optimize ExpandTypeVisitor (#19461)
Specialize a hot for loop for the concrete `tuple` and `list` types. Also add a fast path for empty type arguments. The approach is similar to what I used in #19459. This is a part of a set of micro-optimizations that improve self check performance by ~5.5%.
1 parent ca738e5 commit 5f5871d

File tree

1 file changed

+20
-5
lines changed

1 file changed

+20
-5
lines changed

mypy/expandtype.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from __future__ import annotations
22

3-
from collections.abc import Iterable, Mapping, Sequence
3+
from collections.abc import Iterable, Mapping
44
from typing import Final, TypeVar, cast, overload
55

66
from mypy.nodes import ARG_STAR, FakeInfo, Var
@@ -209,7 +209,11 @@ def visit_erased_type(self, t: ErasedType) -> Type:
209209
return t
210210

211211
def visit_instance(self, t: Instance) -> Type:
212-
args = self.expand_types_with_unpack(list(t.args))
212+
if len(t.args) == 0:
213+
# TODO: Why do we need to create a copy here?
214+
return t.copy_modified()
215+
216+
args = self.expand_type_tuple_with_unpack(t.args)
213217

214218
if isinstance(t.type, FakeInfo):
215219
# The type checker expands function definitions and bodies
@@ -431,7 +435,7 @@ def visit_overloaded(self, t: Overloaded) -> Type:
431435
items.append(new_item)
432436
return Overloaded(items)
433437

434-
def expand_types_with_unpack(self, typs: Sequence[Type]) -> list[Type]:
438+
def expand_type_list_with_unpack(self, typs: list[Type]) -> list[Type]:
435439
"""Expands a list of types that has an unpack."""
436440
items: list[Type] = []
437441
for item in typs:
@@ -441,8 +445,19 @@ def expand_types_with_unpack(self, typs: Sequence[Type]) -> list[Type]:
441445
items.append(item.accept(self))
442446
return items
443447

448+
def expand_type_tuple_with_unpack(self, typs: tuple[Type, ...]) -> list[Type]:
449+
"""Expands a tuple of types that has an unpack."""
450+
# Micro-optimization: Specialized variant of expand_type_list_with_unpack
451+
items: list[Type] = []
452+
for item in typs:
453+
if isinstance(item, UnpackType) and isinstance(item.type, TypeVarTupleType):
454+
items.extend(self.expand_unpack(item))
455+
else:
456+
items.append(item.accept(self))
457+
return items
458+
444459
def visit_tuple_type(self, t: TupleType) -> Type:
445-
items = self.expand_types_with_unpack(t.items)
460+
items = self.expand_type_list_with_unpack(t.items)
446461
if len(items) == 1:
447462
# Normalize Tuple[*Tuple[X, ...]] -> Tuple[X, ...]
448463
item = items[0]
@@ -510,7 +525,7 @@ def visit_type_type(self, t: TypeType) -> Type:
510525
def visit_type_alias_type(self, t: TypeAliasType) -> Type:
511526
# Target of the type alias cannot contain type variables (not bound by the type
512527
# alias itself), so we just expand the arguments.
513-
args = self.expand_types_with_unpack(t.args)
528+
args = self.expand_type_list_with_unpack(t.args)
514529
# TODO: normalize if target is Tuple, and args are [*tuple[X, ...]]?
515530
return t.copy_modified(args=args)
516531

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy