Skip to content

Commit e8ae122

Browse files
authored
Couple obvious optimizations for type aliases (python#8099)
This PR: * Removes three unused slots * Makes recursivity test once per alias * Documents an existing optimization (accidentally made before) The effect of this it at the limit of precision on my laptop, but it looks like this gives around 1% speed-up (for cold runs).
1 parent 9d10a3e commit e8ae122

File tree

3 files changed

+15
-7
lines changed

3 files changed

+15
-7
lines changed

mypy/nodes.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2741,7 +2741,7 @@ def f(x: B[T]) -> T: ... # without T, Any would be used here
27412741
line and column: Line an column on the original alias definition.
27422742
"""
27432743
__slots__ = ('target', '_fullname', 'alias_tvars', 'no_args', 'normalized',
2744-
'line', 'column', 'assuming', 'assuming_proper', 'inferring')
2744+
'line', 'column', '_is_recursive')
27452745

27462746
def __init__(self, target: 'mypy.types.Type', fullname: str, line: int, column: int,
27472747
*,
@@ -2755,6 +2755,9 @@ def __init__(self, target: 'mypy.types.Type', fullname: str, line: int, column:
27552755
self.alias_tvars = alias_tvars
27562756
self.no_args = no_args
27572757
self.normalized = normalized
2758+
# This attribute is manipulated by TypeAliasType. If non-None,
2759+
# it is the cached value.
2760+
self._is_recursive = None # type: Optional[bool]
27582761
super().__init__(line, column)
27592762

27602763
@property

mypy/semanal.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2514,6 +2514,9 @@ def check_and_set_up_type_alias(self, s: AssignmentStmt) -> bool:
25142514
# so we need to replace it with non-explicit Anys.
25152515
if not has_placeholder(res):
25162516
res = make_any_non_explicit(res)
2517+
# Note: with the new (lazy) type alias representation we only need to set no_args to True
2518+
# if the expected number of arguments is non-zero, so that aliases like A = List work.
2519+
# However, eagerly expanding aliases like Text = str is a nice performance optimization.
25172520
no_args = isinstance(res, Instance) and not res.args # type: ignore
25182521
fix_instance_types(res, self.fail, self.note)
25192522
alias_node = TypeAlias(res, self.qualified_name(lvalue.name), s.line, s.column,

mypy/types.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -166,14 +166,13 @@ class Node:
166166
can be represented in a tree-like manner.
167167
"""
168168

169-
__slots__ = ('alias', 'args', 'line', 'column', 'type_ref', '_is_recursive')
169+
__slots__ = ('alias', 'args', 'line', 'column', 'type_ref')
170170

171171
def __init__(self, alias: Optional[mypy.nodes.TypeAlias], args: List[Type],
172172
line: int = -1, column: int = -1) -> None:
173173
self.alias = alias
174174
self.args = args
175175
self.type_ref = None # type: Optional[str]
176-
self._is_recursive = None # type: Optional[bool]
177176
super().__init__(line, column)
178177

179178
def _expand_once(self) -> Type:
@@ -212,10 +211,13 @@ def expand_all_if_possible(self) -> Optional['ProperType']:
212211

213212
@property
214213
def is_recursive(self) -> bool:
215-
if self._is_recursive is not None:
216-
return self._is_recursive
217-
is_recursive = self.expand_all_if_possible() is None
218-
self._is_recursive = is_recursive
214+
assert self.alias is not None, 'Unfixed type alias'
215+
is_recursive = self.alias._is_recursive
216+
if is_recursive is None:
217+
is_recursive = self.expand_all_if_possible() is None
218+
# We cache the value on the underlying TypeAlias node as an optimization,
219+
# since the value is the same for all instances of the same alias.
220+
self.alias._is_recursive = is_recursive
219221
return is_recursive
220222

221223
def can_be_true_default(self) -> bool:

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