Skip to content

Commit 14573d5

Browse files
committed
Some tweaks to use implicit caching
1 parent 37218fd commit 14573d5

File tree

4 files changed

+26
-21
lines changed

4 files changed

+26
-21
lines changed

mypy/indirection.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,15 @@ def find_modules(self, typs: Iterable[types.Type]) -> set[str]:
3737
return self.modules
3838

3939
def _visit(self, typ: types.Type) -> None:
40-
if isinstance(typ, types.TypeAliasType) and typ.is_recursive:
40+
if isinstance(typ, types.TypeAliasType):
4141
# Avoid infinite recursion for recursive type aliases.
4242
self.seen_aliases.add(typ)
4343
typ.accept(self)
4444

4545
def _visit_type_tuple(self, typs: tuple[types.Type, ...]) -> None:
4646
# Micro-optimization: Specialized version of _visit for lists
4747
for typ in typs:
48-
if isinstance(typ, types.TypeAliasType) and typ.is_recursive:
48+
if isinstance(typ, types.TypeAliasType):
4949
# Avoid infinite recursion for recursive type aliases.
5050
if typ in self.seen_aliases:
5151
continue
@@ -55,7 +55,7 @@ def _visit_type_tuple(self, typs: tuple[types.Type, ...]) -> None:
5555
def _visit_type_list(self, typs: list[types.Type]) -> None:
5656
# Micro-optimization: Specialized version of _visit for tuples
5757
for typ in typs:
58-
if isinstance(typ, types.TypeAliasType) and typ.is_recursive:
58+
if isinstance(typ, types.TypeAliasType):
5959
# Avoid infinite recursion for recursive type aliases.
6060
if typ in self.seen_aliases:
6161
continue

mypy/semanal_typeargs.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,14 @@ def visit_type_alias_type(self, t: TypeAliasType) -> None:
100100
if not is_error:
101101
# If there was already an error for the alias itself, there is no point in checking
102102
# the expansion, most likely it will result in the same kind of error.
103-
get_proper_type(t).accept(self)
104103
if t.alias is not None:
105104
t.alias.accept(self)
105+
if t.args:
106+
# Since we always allow unbounded type variables in alias definitions, we need
107+
# to verify the arguments satisfy the upper bounds of the expansion as well.
108+
get_proper_type(t).accept(self)
109+
if t.is_recursive:
110+
self.seen_aliases.discard(t)
106111

107112
def visit_tuple_type(self, t: TupleType) -> None:
108113
t.items = flatten_nested_tuples(t.items)

mypy/type_visitor.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -445,13 +445,13 @@ def visit_placeholder_type(self, t: PlaceholderType, /) -> T:
445445
def visit_type_alias_type(self, t: TypeAliasType, /) -> T:
446446
if self.skip_alias_target:
447447
return self.query_types(t.args)
448-
# Skip type aliases already visited types to avoid infinite recursion.
449-
if t.is_recursive:
450-
if self.seen_aliases is None:
451-
self.seen_aliases = set()
452-
elif t in self.seen_aliases:
453-
return self.strategy([])
454-
self.seen_aliases.add(t)
448+
# Skip type aliases already visited types to avoid infinite recursion
449+
# (also use this as a simple-minded cache).
450+
if self.seen_aliases is None:
451+
self.seen_aliases = set()
452+
elif t in self.seen_aliases:
453+
return self.strategy([])
454+
self.seen_aliases.add(t)
455455
return get_proper_type(t).accept(self)
456456

457457
def query_types(self, types: Iterable[Type]) -> T:
@@ -586,13 +586,13 @@ def visit_placeholder_type(self, t: PlaceholderType, /) -> bool:
586586
def visit_type_alias_type(self, t: TypeAliasType, /) -> bool:
587587
if self.skip_alias_target:
588588
return self.query_types(t.args)
589-
# Skip type aliases already visited types to avoid infinite recursion.
590-
if t.is_recursive:
591-
if self.seen_aliases is None:
592-
self.seen_aliases = set()
593-
elif t in self.seen_aliases:
594-
return self.default
595-
self.seen_aliases.add(t)
589+
# Skip type aliases already visited types to avoid infinite recursion
590+
# (also use this as a simple-minded cache).
591+
if self.seen_aliases is None:
592+
self.seen_aliases = set()
593+
elif t in self.seen_aliases:
594+
return self.default
595+
self.seen_aliases.add(t)
596596
return get_proper_type(t).accept(self)
597597

598598
def query_types(self, types: list[Type] | tuple[Type, ...]) -> bool:

test-data/unit/check-recursive-types.test

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ class A(NamedTuple('A', [('attr', List[Exp])])): pass
189189
class B(NamedTuple('B', [('val', object)])): pass
190190

191191
def my_eval(exp: Exp) -> int:
192-
reveal_type(exp) # N: Revealed type is "Union[tuple[builtins.list[Union[..., tuple[builtins.object, fallback=__main__.B]]], fallback=__main__.A], tuple[builtins.object, fallback=__main__.B]]"
192+
reveal_type(exp) # N: Revealed type is "Union[tuple[builtins.list[...], fallback=__main__.A], tuple[builtins.object, fallback=__main__.B]]"
193193
if isinstance(exp, A):
194194
my_eval(exp[0][0])
195195
return my_eval(exp.attr[0])
@@ -578,7 +578,7 @@ B = NamedTuple('B', [('x', A), ('y', int)])
578578
A = NamedTuple('A', [('x', str), ('y', 'B')])
579579
n: A
580580
def f(m: B) -> None: pass
581-
reveal_type(n) # N: Revealed type is "tuple[builtins.str, tuple[tuple[builtins.str, ..., fallback=__main__.A], builtins.int, fallback=__main__.B], fallback=__main__.A]"
581+
reveal_type(n) # N: Revealed type is "tuple[builtins.str, tuple[..., builtins.int, fallback=__main__.B], fallback=__main__.A]"
582582
reveal_type(f) # N: Revealed type is "def (m: tuple[tuple[builtins.str, ..., fallback=__main__.A], builtins.int, fallback=__main__.B])"
583583
f(n) # E: Argument 1 to "f" has incompatible type "A"; expected "B"
584584
[builtins fixtures/tuple.pyi]
@@ -1013,4 +1013,4 @@ from typing import Callable
10131013
from bogus import Foo # type: ignore
10141014

10151015
A = Callable[[Foo, "B"], Foo] # E: Type alias target becomes "Callable[[Any, B], Any]" due to an unfollowed import
1016-
B = Callable[[Foo, A], Foo] # E: Type alias target becomes "Callable[[Any, Callable[[Any, B], Any]], Any]" due to an unfollowed import
1016+
B = Callable[[Foo, A], Foo] # E: Type alias target becomes "Callable[[Any, A], Any]" due to an unfollowed import

0 commit comments

Comments
 (0)