From 35c1932e4600b41ce21f6e3d7074850590b2bbbf Mon Sep 17 00:00:00 2001 From: onerandomusername Date: Sat, 13 Aug 2022 02:22:40 -0400 Subject: [PATCH 1/4] fix!: persist other features when changing the community feature --- disnake/guild.py | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/disnake/guild.py b/disnake/guild.py index ac23d819c8..64257b895e 100644 --- a/disnake/guild.py +++ b/disnake/guild.py @@ -1975,16 +1975,36 @@ async def edit( fields["system_channel_flags"] = system_channel_flags.value if community is not MISSING: - features = [] + # if we don't have complete feature information for the guild + # it is possible to disable or enable other features that we didn't intend to touch + # The issue is removing community also removes partner status, and discord is adding the ability to + # enable or disable invite usage for guilds, which is problematically triggered by a feature. + # To enable or disable that feature, we will need to provide all of the existing features in advance. + # That is problematic to say the least. By reimplementing this list to only provide the features if we make a change + # we minimize the possible times that we will provide features when no changes are made, and possibly affect other features. + if self.unavailable: + raise RuntimeError( + "cannot modify features of an unavailable guild due to potentially destructive results." + ) + features = self.features if community: if "rules_channel_id" in fields and "public_updates_channel_id" in fields: - features.append("COMMUNITY") + if "COMMUNITY" not in features: + features.append("COMMUNITY") + else: + features = MISSING else: raise ValueError( "community field requires both rules_channel and public_updates_channel fields to be provided" ) + else: + try: + features.remove("COMMUNITY") + except ValueError: + features = MISSING - fields["features"] = features + if features is not MISSING: + fields["features"] = features if premium_progress_bar_enabled is not MISSING: fields["premium_progress_bar_enabled"] = premium_progress_bar_enabled From 64c99e5d076b2193510afd4e91375de00a894f47 Mon Sep 17 00:00:00 2001 From: onerandomusername Date: Sat, 13 Aug 2022 02:26:10 -0400 Subject: [PATCH 2/4] docs: add changelog fragment --- changelog/705.bugfix.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog/705.bugfix.rst diff --git a/changelog/705.bugfix.rst b/changelog/705.bugfix.rst new file mode 100644 index 0000000000..0848932e8b --- /dev/null +++ b/changelog/705.bugfix.rst @@ -0,0 +1 @@ +Fixed an issue where it would be possible to remove other features when enabling or disabling the ``COMMUNITY`` feature for a :class:`.Guild`. From badbf3f29b225c6bb274f88a910581c4f6c15eb8 Mon Sep 17 00:00:00 2001 From: onerandomusername Date: Fri, 26 Aug 2022 21:43:58 -0400 Subject: [PATCH 3/4] refactor features slightly to be easier to expand --- disnake/guild.py | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/disnake/guild.py b/disnake/guild.py index 64257b895e..99a7b3f88f 100644 --- a/disnake/guild.py +++ b/disnake/guild.py @@ -1986,25 +1986,21 @@ async def edit( raise RuntimeError( "cannot modify features of an unavailable guild due to potentially destructive results." ) - features = self.features - if community: - if "rules_channel_id" in fields and "public_updates_channel_id" in fields: - if "COMMUNITY" not in features: - features.append("COMMUNITY") + features = set(self.features) + if community is not MISSING: + if not isinstance(community, bool): + raise TypeError("community must be a bool instance") + if community: + if "rules_channel_id" in fields and "public_updates_channel_id" in fields: + features.add("COMMUNITY") else: - features = MISSING + raise ValueError( + "community field requires both rules_channel and public_updates_channel fields to be provided" + ) else: - raise ValueError( - "community field requires both rules_channel and public_updates_channel fields to be provided" - ) - else: - try: - features.remove("COMMUNITY") - except ValueError: - features = MISSING + features.discard("COMMUNITY") - if features is not MISSING: - fields["features"] = features + fields["features"] = list(features) if premium_progress_bar_enabled is not MISSING: fields["premium_progress_bar_enabled"] = premium_progress_bar_enabled From e8e5fa328626cba8ffaf9e5f56396c34b309d452 Mon Sep 17 00:00:00 2001 From: arl Date: Sat, 27 Aug 2022 10:19:00 -0400 Subject: [PATCH 4/4] chore: bring comment in sync with code Co-authored-by: shiftinv <8530778+shiftinv@users.noreply.github.com> --- disnake/guild.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/disnake/guild.py b/disnake/guild.py index 99a7b3f88f..c654cbe1b8 100644 --- a/disnake/guild.py +++ b/disnake/guild.py @@ -1975,13 +1975,9 @@ async def edit( fields["system_channel_flags"] = system_channel_flags.value if community is not MISSING: - # if we don't have complete feature information for the guild - # it is possible to disable or enable other features that we didn't intend to touch - # The issue is removing community also removes partner status, and discord is adding the ability to - # enable or disable invite usage for guilds, which is problematically triggered by a feature. - # To enable or disable that feature, we will need to provide all of the existing features in advance. - # That is problematic to say the least. By reimplementing this list to only provide the features if we make a change - # we minimize the possible times that we will provide features when no changes are made, and possibly affect other features. + # If we don't have complete feature information for the guild, + # it is possible to disable or enable other features that we didn't intend to touch. + # To enable or disable a feature, we will need to provide all of the existing features in advance. if self.unavailable: raise RuntimeError( "cannot modify features of an unavailable guild due to potentially destructive results."