From 89a88cc1158ba9b71d6f1fea4d569148853d594b 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 | 18 ++++++++++++++++-- discord/state.py | 5 +++++ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/discord/guild.py b/discord/guild.py index 4aa928766..578ed87e4 100644 --- a/discord/guild.py +++ b/discord/guild.py @@ -549,10 +549,11 @@ class Guild(Hashable): def _remove_thread(self, thread: Snowflake, /) -> None: self._threads.pop(thread.id, None) - 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]: return {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 cf2af7a39..66ce02b05 100644 --- a/discord/raw_models.py +++ b/discord/raw_models.py @@ -24,10 +24,10 @@ DEALINGS IN THE SOFTWARE. from __future__ import annotations -from typing import TYPE_CHECKING, Literal, Optional, Set, List, Tuple, Union +from typing import TYPE_CHECKING, List, Literal, Optional, Set, Tuple, Union -from .enums import ChannelType, ReadStateType, try_enum from .colour import Colour +from .enums import ChannelType, ReadStateType, try_enum from .utils import _get_as_snowflake if TYPE_CHECKING: @@ -364,6 +364,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 0428ce0b6..a29b81013 100644 --- a/discord/state.py +++ b/discord/state.py @@ -2126,6 +2126,11 @@ class ConnectionState: if s.channel_id == channel.id: 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)) else: channel = self._get_private_channel(channel_id) if channel is not None: