Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix app command copies #678

Merged
merged 10 commits into from
Aug 25, 2022
1 change: 1 addition & 0 deletions changelog/678.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Make the :func:`.ext.commands.default_member_permissions` decorator always work in cogs.
6 changes: 6 additions & 0 deletions disnake/ext/commands/base_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,12 @@ def _ensure_assignment_on_copy(self, other: AppCommandT) -> AppCommandT:
# _max_concurrency won't be None at this point
other._max_concurrency = cast(MaxConcurrency, self._max_concurrency).copy()

if self.body._default_member_permissions != other.body._default_member_permissions and (
"default_member_permissions" not in other.__original_kwargs__
or self.body._default_member_permissions is not None
):
other.body._default_member_permissions = self.body._default_member_permissions

try:
other.on_error = self.on_error
except AttributeError:
Expand Down
8 changes: 1 addition & 7 deletions disnake/ext/commands/ctx_menus_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,15 +205,9 @@ def __init__(
self.auto_sync: bool = True if auto_sync is None else auto_sync

try:
default_perms: int = func.__default_member_permissions__
default_member_permissions = func.__default_member_permissions__
except AttributeError:
pass
else:
if default_member_permissions is not None:
raise ValueError(
"Cannot set `default_member_permissions` in both parameter and decorator"
)
default_member_permissions = default_perms

dm_permission = True if dm_permission is None else dm_permission

Expand Down
8 changes: 1 addition & 7 deletions disnake/ext/commands/slash_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -417,15 +417,9 @@ def __init__(
desc_loc = Localized._cast(description, False)

try:
default_perms: int = func.__default_member_permissions__
default_member_permissions = func.__default_member_permissions__
except AttributeError:
pass
else:
if default_member_permissions is not None:
raise ValueError(
"Cannot set `default_member_permissions` in both parameter and decorator"
)
default_member_permissions = default_perms

dm_permission = True if dm_permission is None else dm_permission

Expand Down
82 changes: 82 additions & 0 deletions tests/ext/commands/test_base_core.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import pytest

from disnake import Permissions
from disnake.ext import commands


class TestDefaultPermissions:
def test_decorator(self):
class Cog(commands.Cog):
@commands.slash_command(default_member_permissions=64)
async def cmd(self, _):
...

@commands.default_member_permissions(64)
@commands.slash_command()
async def above(self, _):
...

@commands.slash_command()
@commands.default_member_permissions(64)
async def below(self, _):
...

for c in (Cog, Cog()):
assert c.cmd.default_member_permissions == Permissions(64)
assert c.above.default_member_permissions == Permissions(64)
assert c.below.default_member_permissions == Permissions(64)

def test_decorator_overwrite(self):
# putting the decorator above should fail
with pytest.raises(ValueError, match="Cannot set `default_member_permissions`"):

class Cog(commands.Cog):
@commands.default_member_permissions(32)
@commands.slash_command(default_member_permissions=64)
async def above(self, _):
...

# putting the decorator below shouldn't fail
# (this is a side effect of how command copying works,
# and while this *should* probably fail, we're just testing
# for regressions for now)
class Cog2(commands.Cog):
@commands.slash_command(default_member_permissions=64)
@commands.default_member_permissions(32)
async def below(self, _):
...

for c in (Cog2, Cog2()):
assert c.below.default_member_permissions == Permissions(32)

def test_attrs(self):
class Cog(commands.Cog, slash_command_attrs={"default_member_permissions": 32}):
@commands.slash_command()
async def no_overwrite(self, _):
...

@commands.slash_command(default_member_permissions=64)
async def overwrite(self, _):
...

@commands.default_member_permissions(64)
@commands.slash_command()
async def overwrite_decorator_above(self, _):
...

@commands.slash_command()
@commands.default_member_permissions(64)
async def overwrite_decorator_below(self, _):
...

assert Cog.no_overwrite.default_member_permissions is None
assert Cog().no_overwrite.default_member_permissions == Permissions(32)

assert Cog.overwrite.default_member_permissions == Permissions(64)
assert Cog().overwrite.default_member_permissions == Permissions(64)

assert Cog.overwrite_decorator_above.default_member_permissions == Permissions(64)
assert Cog().overwrite_decorator_above.default_member_permissions == Permissions(64)

assert Cog.overwrite_decorator_below.default_member_permissions == Permissions(64)
assert Cog().overwrite_decorator_below.default_member_permissions == Permissions(64)