From 0ee1794c6de7bd61e8fca6bd0b98211b93e331c3 Mon Sep 17 00:00:00 2001 From: Lilly Rose Berner Date: Sun, 5 May 2024 05:23:59 +0200 Subject: [PATCH] Fix channel deletion not removing associated threads --- discord/guild.py | 9 +++++---- discord/raw_models.py | 16 ++++++++++++++++ discord/state.py | 6 ++++++ 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/discord/guild.py b/discord/guild.py index c038188c8..6d1c5bde3 100644 --- a/discord/guild.py +++ b/discord/guild.py @@ -378,10 +378,11 @@ class Guild(Hashable): def _clear_threads(self) -> None: self._threads.clear() - def _remove_threads_by_channel(self, channel_id: int) -> None: - to_remove = [k for k, t in self._threads.items() if t.parent_id == channel_id] - for k in to_remove: - del self._threads[k] + def _remove_threads_by_channel(self, channel_id: int) -> List[Thread]: + to_remove = [t for t in self._threads.values() if t.parent_id == channel_id] + for thread in to_remove: + del self._threads[thread.id] + return to_remove def _filter_threads(self, channel_ids: Set[int]) -> Dict[int, Thread]: to_remove: Dict[int, Thread] = {k: t for k, t in self._threads.items() if t.parent_id in channel_ids} diff --git a/discord/raw_models.py b/discord/raw_models.py index 74382b3f8..2fd94539e 100644 --- a/discord/raw_models.py +++ b/discord/raw_models.py @@ -33,6 +33,8 @@ from .app_commands import AppCommandPermissions from .colour import Colour if TYPE_CHECKING: + from typing_extensions import Self + from .types.gateway import ( MessageDeleteEvent, MessageDeleteBulkEvent as BulkMessageDeleteEvent, @@ -399,6 +401,20 @@ class RawThreadDeleteEvent(_RawReprMixin): self.parent_id: int = int(data['parent_id']) self.thread: Optional[Thread] = None + @classmethod + def _from_thread(cls, thread: Thread) -> Self: + data: ThreadDeleteEvent = { + 'id': thread.id, + 'type': thread.type.value, + 'guild_id': thread.guild.id, + 'parent_id': thread.parent_id, + } + + instance = cls(data) + instance.thread = thread + + return instance + class RawThreadMembersUpdate(_RawReprMixin): """Represents the payload for a :func:`on_raw_thread_member_remove` event. diff --git a/discord/state.py b/discord/state.py index b3da4eabf..fbde85cf0 100644 --- a/discord/state.py +++ b/discord/state.py @@ -831,6 +831,12 @@ class ConnectionState(Generic[ClientT]): guild._scheduled_events.pop(s.id) self.dispatch('scheduled_event_delete', s) + threads = guild._remove_threads_by_channel(channel_id) + + for thread in threads: + self.dispatch('thread_delete', thread) + self.dispatch('raw_thread_delete', RawThreadDeleteEvent._from_thread(thread)) + def parse_channel_update(self, data: gw.ChannelUpdateEvent) -> None: channel_type = try_enum(ChannelType, data.get('type')) channel_id = int(data['id'])