Skip to content

Fix various crahses on recursive type variable defaults#21491

Open
ilevkivskyi wants to merge 11 commits into
python:masterfrom
ilevkivskyi:fix-tv-default-crashes
Open

Fix various crahses on recursive type variable defaults#21491
ilevkivskyi wants to merge 11 commits into
python:masterfrom
ilevkivskyi:fix-tv-default-crashes

Conversation

@ilevkivskyi
Copy link
Copy Markdown
Member

@ilevkivskyi ilevkivskyi commented May 15, 2026

Fixes #17716
Fixes #20698
Fixes #21128
Fixes #21269

Although the main idea is relatively simple (replace explicit type variable defaults with Any in cases where they would cause infinite recursion), this required a lot of "plumbing", because:

  • We always call fix_instance() eagerly and early.
  • There are four different cases to handle (classes vs aliases, and old style vs new style).
  • Relevant pieces of information are available in "distant" places (and I don't want to add any global state).

Some additional notes:

  • I clean-up some weirdness with deferral on type variable defaults with placeholders (especially in type aliases).
  • I remove an unwarranted get_proper_type() call during semantic analysis.
  • Now we handle rare edge case of unused alias type variables in BoolTypeQuery (possible with new style aliases).
  • Type variable defaults should be considered in __eq__() to correctly detect progress.

@github-actions

This comment has been minimized.

@ilevkivskyi
Copy link
Copy Markdown
Member Author

Hm, it looks like something went wrong. I will take a look later today or tomorrow.

@github-actions

This comment has been minimized.

@ilevkivskyi
Copy link
Copy Markdown
Member Author

OK, this is ready for review now.

Btw the mypy_primer changes in steam.py are good illustration of why I took this (more complex) approach rather than trying to tune mark_incomplete() usage.

@ilevkivskyi
Copy link
Copy Markdown
Member Author

Oh, it looks like this fixes #20698 as well.

@ilevkivskyi
Copy link
Copy Markdown
Member Author

@JukkaL @hauntsaninja @cdce8p Ping here.

@github-actions

This comment has been minimized.

@github-actions
Copy link
Copy Markdown
Contributor

Diff from mypy_primer, showing the effect of this PR on open source code:

steam.py (https://github.com/Gobot1234/steam.py)
- steam/_const.py:29: error: Module "steam.clan" has no attribute "Clan"  [attr-defined]
- steam/_const.py:30: error: Module "steam.group" has no attribute "Group"  [attr-defined]
- steam/types/user.py:16: error: Module "steam.user" has no attribute "User"  [attr-defined]
- steam/types/user.py:139: error: Cannot resolve name "Author" (possible cyclic definition)  [misc]
- steam/invite.py:16: error: Module "steam.clan" has no attribute "Clan"  [attr-defined]
- steam/invite.py:19: error: Module "steam.group" has no attribute "Group"  [attr-defined]
- steam/invite.py:21: error: Module "steam.user" has no attribute "User"  [attr-defined]
- steam/invite.py:118: error: Cannot resolve name "ChatGroupInvite" (possible cyclic definition)  [misc]
- steam/ext/commands/errors.py:12: error: Module "steam.ext.commands.commands" has no attribute "Command"; maybe "command"?  [attr-defined]
- steam/role.py:15: error: Module "steam.chat" has no attribute "ChatGroup"  [attr-defined]
- steam/role.py:15: error: Module "steam.chat" has no attribute "Member"; maybe "MemberT"?  [attr-defined]
- steam/role.py:16: error: Module "steam.clan" has no attribute "Clan"  [attr-defined]
- steam/role.py:17: error: Module "steam.group" has no attribute "Group"  [attr-defined]
- steam/app.py:41: error: Module "steam.clan" has no attribute "Clan"  [attr-defined]
- steam/app.py:42: error: Module "steam.friend" has no attribute "Friend"  [attr-defined]
- steam/app.py:396: error: Cannot resolve Self upper bound (possible cyclic definition)  [misc]
- steam/trade.py:27: error: Module "steam.friend" has no attribute "Friend"  [attr-defined]
- steam/trade.py:30: error: Module "steam.user" has no attribute "User"  [attr-defined]
- steam/reaction.py:22: error: Module "steam.message" does not explicitly export attribute "Message"  [attr-defined]
- steam/package.py:29: error: Module "steam.user" has no attribute "User"  [attr-defined]
- steam/profile.py:26: error: Module "steam.clan" has no attribute "Clan"  [attr-defined]
- steam/profile.py:27: error: Module "steam.friend" has no attribute "Friend"  [attr-defined]
- steam/profile.py:32: error: Module "steam.user" has no attribute "User"  [attr-defined]
- steam/abc.py:37: error: Module "steam.clan" has no attribute "Clan"  [attr-defined]
- steam/abc.py:38: error: Module "steam.comment" has no attribute "Comment"; maybe "CommentID" or "Commentable"?  [attr-defined]
- steam/abc.py:40: error: Module "steam.group" has no attribute "Group"  [attr-defined]
- steam/abc.py:43: error: Module "steam.message" has no attribute "UserMessage"; maybe "Message" or "UserMessageAuthorT"?  [attr-defined]
- steam/abc.py:49: error: Module "steam.user" has no attribute "User"  [attr-defined]
- steam/abc.py:58: error: Cannot resolve name "Message" (possible cyclic definition)  [misc]
- steam/abc.py:58: error: TypeVar "bound" must be a type  [misc]
- steam/abc.py:58: error: TypeVar "default" must be a type  [misc]
- steam/user.py:33: error: Module "steam.channel" has no attribute "UserChannel"; maybe "Channel"?  [attr-defined]
- steam/user.py:34: error: Module "steam.friend" has no attribute "Friend"  [attr-defined]
- steam/user.py:36: error: Module "steam.message" has no attribute "UserMessage"; maybe "Message" or "UserMessageAuthorT"?  [attr-defined]
- steam/published_file.py:28: error: Module "steam.friend" has no attribute "Friend"  [attr-defined]
+ steam/published_file.py:509: error: List comprehension has incompatible type List[Friend | None]; expected List[Friend]  [misc]
- steam/event.py:22: error: Module "steam.clan" has no attribute "Clan"  [attr-defined]
- steam/chat.py:37: error: Module "steam.clan" has no attribute "Clan"  [attr-defined]
- steam/chat.py:38: error: Module "steam.group" has no attribute "Group"  [attr-defined]
- steam/chat.py:41: error: Module "steam.message" has no attribute "ClanMessage"; maybe "ChatMessage", "Message", or "ClanMessageAuthorT"?  [attr-defined]
- steam/chat.py:41: error: Module "steam.message" has no attribute "GroupMessage"; maybe "GroupMessageAuthorT"?  [attr-defined]
- steam/chat.py:45: error: Cannot resolve name "Chat" (possible cyclic definition)  [misc]
- steam/chat.py:45: error: TypeVar "bound" must be a type  [misc]
- steam/chat.py:45: error: TypeVar "default" must be a type  [misc]
- steam/chat.py:46: error: Cannot resolve name "Member" (possible cyclic definition)  [misc]
- steam/chat.py:46: error: TypeVar "bound" must be a type  [misc]
- steam/chat.py:46: error: TypeVar "default" must be a type  [misc]
- steam/chat.py:412: error: Unused "type: ignore" comment  [unused-ignore]
+ steam/chat.py:402: error: List item 0 has incompatible type "type[ClanT]"; expected "type[Group] | type[None] | type[Clan]"  [list-item]
+ steam/chat.py:402: error: List item 1 has incompatible type "type[GroupT]"; expected "type[Group] | type[None] | type[Clan]"  [list-item]
+ steam/chat.py:428: error: Argument 1 to "append" of "list" has incompatible type "GroupMessage[PartialMember | GroupMember] | ClanMessage[PartialMember | ClanMember]"; expected "ChatMessageT"  [arg-type]
- steam/message.py:15: error: Module "steam.channel" has no attribute "ClanChannel"; maybe "Channel"?  [attr-defined]
- steam/message.py:15: error: Module "steam.channel" has no attribute "GroupChannel"; maybe "GroupChannelProtos"?  [attr-defined]
- steam/message.py:15: error: Module "steam.channel" has no attribute "UserChannel"; maybe "Channel"?  [attr-defined]
- steam/message.py:16: error: Module "steam.clan" has no attribute "Clan"  [attr-defined]
- steam/message.py:16: error: Module "steam.clan" has no attribute "ClanMember"  [attr-defined]
- steam/message.py:18: error: Module "steam.group" has no attribute "Group"  [attr-defined]
- steam/message.py:18: error: Module "steam.group" has no attribute "GroupMember"  [attr-defined]
- steam/channel.py:16: error: Module "steam.clan" has no attribute "Clan"  [attr-defined]
- steam/channel.py:18: error: Module "steam.group" has no attribute "Group"  [attr-defined]
- steam/group.py:24: error: Cannot resolve name "Group" (possible cyclic definition)  [misc]
- steam/clan.py:55: error: TypeVar "bound" must be a type  [misc]
- steam/clan.py:58: error: Cannot resolve name "Clan" (possible cyclic definition)  [misc]
- steam/state.py:1476: error: Unused "type: ignore" comment  [unused-ignore]
- steam/state.py:1515: error: Unused "type: ignore" comment  [unused-ignore]
+ steam/state.py:2400: error: Argument 1 to "add" of "set" has incompatible type "CommentID | _ReadOnlyProto[CommentID]"; expected "int"  [arg-type]
- steam/client.py:74: error: Module "steam.ext.commands.bot" has no attribute "Bot"  [attr-defined]
+ steam/client.py:1290: error: Redundant cast to "list[TradeOffer[MovedItem[User], MovedItem[ClientUser], User]]"  [redundant-cast]
+ steam/client.py:1906: error: The erased type of self "steam.ext.commands.bot.Bot" is not a supertype of its class "steam.client.Client"  [misc]
+ steam/client.py:1915: error: The erased type of self "steam.ext.commands.bot.Bot" is not a supertype of its class "steam.client.Client"  [misc]
- steam/ext/commands/cooldown.py:16: error: Module "steam.ext.commands.context" has no attribute "Context"  [attr-defined]
- steam/ext/commands/cooldown.py:71: error: Argument 1 to "BucketTypeType" has incompatible type "Any | Role | RoleID | None"; expected "int | None"  [arg-type]
+ steam/ext/commands/cooldown.py:71: error: Argument 1 to "BucketTypeType" has incompatible type "Clan | Role | RoleID | None"; expected "int | None"  [arg-type]
+ steam/ext/commands/cooldown.py:77: error: Argument 1 to "BucketTypeType" has incompatible type "Clan | bool | None"; expected "int | None"  [arg-type]
- steam/ext/commands/context.py:21: error: Module "steam.ext.commands.bot" has no attribute "Bot"  [attr-defined]
- steam/ext/commands/context.py:22: error: Module "steam.ext.commands.commands" has no attribute "Command"; maybe "command"?  [attr-defined]
- steam/ext/commands/converters.py:44: error: Module "steam.ext.commands.bot" has no attribute "Bot"  [attr-defined]
- steam/ext/commands/commands.py:47: error: Module "steam.ext.commands.bot" has no attribute "Bot"  [attr-defined]
- steam/ext/commands/commands.py:48: error: Module "steam.ext.commands.cog" has no attribute "Cog"; maybe "CogT"?  [attr-defined]
- steam/ext/commands/commands.py:66: error: Cannot resolve name "CheckType" (possible cyclic definition)  [misc]
- steam/ext/commands/commands.py:69: error: Cannot resolve name "Command" (possible cyclic definition)  [misc]
- steam/ext/commands/commands.py:111: error: Cannot resolve name "GroupMixin" (possible cyclic definition)  [misc]
- steam/ext/commands/commands.py:111: error: Cannot resolve name "Group" (possible cyclic definition)  [misc]
- steam/ext/commands/commands.py:117: error: Cannot resolve name "Command" (possible cyclic definition)  [misc]
- steam/ext/commands/commands.py:117: error: TypeVar "bound" must be a type  [misc]
- steam/ext/commands/commands.py:117: error: TypeVar "default" must be a type  [misc]
- steam/ext/commands/commands.py:575: error: Cannot resolve name "CallbackT" (possible cyclic definition)  [misc]
- steam/ext/commands/commands.py:732: error: Unused "type: ignore" comment  [unused-ignore]
- steam/ext/commands/commands.py:831: error: Incompatible return value type (got "Any | Command[Any, Any, Any]", expected "C")  [return-value]
+ steam/ext/commands/commands.py:831: error: Incompatible return value type (got "C | Command[Any, Any, Any]", expected "C")  [return-value]
- steam/ext/commands/help.py:35: error: Redundant cast to "CommandKwargs[Any]"  [redundant-cast]
+ steam/ext/commands/help.py:35: error: Redundant cast to "CommandKwargs[Command[Cog[Bot] | Bot | None, [VarArg(Any), KwArg(Any)], Any]]"  [redundant-cast]
- steam/ext/commands/help.py:138: note:          def on_error(self, ctx: Context[Any], error: Exception) -> Coroutine[Any, Any, None]
+ steam/ext/commands/help.py:138: note:          def on_error(self, ctx: Context[Bot], error: Exception) -> Coroutine[Any, Any, None]
- steam/ext/commands/cog.py:20: error: Module "steam.ext.commands.bot" has no attribute "Bot"  [attr-defined]
- steam/ext/commands/cog.py:25: error: Cannot resolve name "UnboundListenerType" (possible cyclic definition)  [misc]
- steam/ext/commands/bot.py:49: error: Cannot resolve name "CommandPrefixType" (possible cyclic definition)  [misc]
- steam/ext/commands/bot.py:49: error: Cannot resolve name "Bot" (possible cyclic definition)  [misc]
- steam/ext/commands/bot.py:597: error: Unused "type: ignore" comment  [unused-ignore]
- steam/ext/commands/bot.py:599: error: Unused "type: ignore" comment  [unused-ignore]

Tanjun (https://github.com/FasterSpeeding/Tanjun)
- tanjun/hooks.py:191: error: Name "_MaybeAwaitable" is not defined  [name-defined]
- tanjun/hooks.py:207: error: Name "_MaybeAwaitable" is not defined  [name-defined]
- tanjun/hooks.py:221: error: Name "_MaybeAwaitable" is not defined  [name-defined]
- tanjun/components.py:147: error: Name "_MaybeAwaitable" is not defined  [name-defined]
- tanjun/commands/base.py:147: error: Name "_MaybeAwaitable" is not defined  [name-defined]
- tanjun/clients.py:147: error: Name "_MaybeAwaitable" is not defined  [name-defined]

@ilevkivskyi
Copy link
Copy Markdown
Member Author

@JukkaL this is another PR in case you missed it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant