Skip to content

Commit

Permalink
Fix crash when showing partially analyzed type in error message (#17961)
Browse files Browse the repository at this point in the history
Fixes #17954

People say something about cache invalidation being one of the hardest
problems...
  • Loading branch information
ilevkivskyi authored Oct 16, 2024
1 parent 10f3ce5 commit fbae432
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 2 deletions.
8 changes: 6 additions & 2 deletions mypy/semanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -4014,8 +4014,10 @@ def check_and_set_up_type_alias(self, s: AssignmentStmt) -> bool:
# so we need to replace it with non-explicit Anys.
res = make_any_non_explicit(res)
if self.options.disallow_any_unimported and has_any_from_unimported_type(res):
self.msg.unimported_type_becomes_any("Type alias target", res, s)
res = make_any_non_unimported(res)
# Only show error message once, when the type is fully analyzed.
if not has_placeholder(res):
self.msg.unimported_type_becomes_any("Type alias target", res, s)
res = make_any_non_unimported(res)
# Note: with the new (lazy) type alias representation we only need to set no_args to True
# if the expected number of arguments is non-zero, so that aliases like `A = List` work
# but not aliases like `A = TypeAliasType("A", List)` as these need explicit type params.
Expand Down Expand Up @@ -4069,6 +4071,8 @@ def check_and_set_up_type_alias(self, s: AssignmentStmt) -> bool:
existing.node.alias_tvars = alias_tvars
existing.node.no_args = no_args
updated = True
# Invalidate recursive status cache in case it was previously set.
existing.node._is_recursive = None
else:
# Otherwise just replace existing placeholder with type alias.
existing.node = alias_node
Expand Down
8 changes: 8 additions & 0 deletions test-data/unit/check-recursive-types.test
Original file line number Diff line number Diff line change
Expand Up @@ -1006,3 +1006,11 @@ ta: Tuple[A]
p: Proto
p = ta
[builtins fixtures/tuple.pyi]

[case testRecursiveAliasesWithAnyUnimported]
# flags: --disallow-any-unimported
from typing import Callable
from bogus import Foo # type: ignore

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

0 comments on commit fbae432

Please sign in to comment.