@commands.slash_command(dm_permission=False, admin_permission=True)
async def source(self, inter):
await inter.response.defer(ephemeral=True)
if not inter.author.guild_permissions.administrator:
return await inter.followup.send('You must be an administrator to use this command.', ephemeral=True)
guild = await self.guilds_db.find_one({'_id': str(inter.guild.id)})
if not guild:
return await inter.followup.send('You must `/configure` your server first.', ephemeral=True)
inter.guild_object = guild
print("source", self) #working
@source.sub_command_group()
async def channel(self, inter):
print("channel", self) #working
pass
@channel.sub_command()
async def list(self, inter):
"""
List all source channels.
Parameters
----------
inter: necessary for bot commands
"""
print("list", self) #None
guild = inter.guild_object
index_embed = disnake.Embed(
title='**Source Channels**', description="", color=self.color)
channels = []
for channel_id in guild['channels']:
channel = self.bot.get_channel(int(channel_id))
if channel:
channels.append(channel.mention)
if len(channels) > 0:
index_embed.description = "\n".join(channels)
else:
index_embed.description = "None."
await inter.followup.send(embed=index_embed)
#sub_command decorator is not properly preserving the instance (i.e., self) when it's being called
1 messages · Page 1 of 1 (latest)
admin_permission is not a valid kwarg for slash command.
Use commands.has_permissions(administrator=True)
Also, source is a parent command. It is called every single time. So, typically you do not want to have any responses here.
self is the cog instance. Not sure what you're actually trying to do here.
also, can't reproduce it - what version are you using?
simplified, but works fine on my end:
@commands.slash_command()
async def source(self, inter):
print("source", self)
@source.sub_command_group()
async def channel(self, inter):
print("channel", self)
@channel.sub_command()
async def list(self, inter):
print("list", self)
2023-07-07 18:49:57,358: [DEBUG] (MainThread) disnake.client: Dispatching event slash_command
source <test_bot.cogs.misc.Misc object at 0x7f9c927089d0>
channel <test_bot.cogs.misc.Misc object at 0x7f9c927089d0>
list <test_bot.cogs.misc.Misc object at 0x7f9c927089d0>
without the logic, this part works on my end as well. my goal is to have a high level check for anyone running /source related commands. would it be preferable to have checks within the sub_command instead?
cc: @silk juniper
hm i think the issue is the name being list()
You could move the checks to a cog_slash_command_check and cog_slash_command_error handler
But yeah, you shouldn't use reserved python keywords for naming objects.
hmm, not quite sure why that did it, but if it works it works 
in any case, you can use @channel.sub_command(name="list") to keep it as "list" on Discord and name your method whatever you want c:
nevermind, show is still messing it up
@commands.slash_command(dm_permission=False)
@commands.default_member_permissions(administrator=True)
async def source(self, inter):
pass
@source.sub_command_group()
async def channel(self, inter):
print("channel", self)
pass
@channel.sub_command()
async def show(self, inter):
"""
Show all source channels.
"""
print("show", self)
await inter.response.defer(ephemeral=True)
guild = await self.guilds_db.find_one({'_id': str(inter.guild.id)})
if not guild:
return await inter.followup.send('You must `/configure` your server first.', ephemeral=True)
index_embed = disnake.Embed(
title='**Source Channels**', description="", color=self.color)
channels = []
for channel_id in guild['channels']:
channel = self.bot.get_channel(int(channel_id))
if channel:
channels.append(channel.mention)
if len(channels) > 0:
index_embed.description = "\n".join(channels)
else:
index_embed.description = "None."
await inter.followup.send(embed=index_embed)
worked for a little broke again
only way I'm getting around is:
source()
inter.self = self
show()
self = inter.self
I still have no idea what it is you're trying to do.
just adding and displaying items to and from database
guilds_db is the database
i could send the entire file if you'd like
I get that, but I don't understand the involvement of self
thew inter.self part is what is confusing me.
class Core(commands.Cog):
def __init__(self, bot) -> None:
self.bot = bot
self.color = 0xEBE1DB
self.guilds_db = MongoDB('Clarify', 'guilds')
this is my class @silk juniper
I see.
I need to access self.guilds_db and self.bot
Right.
That's just odd.
and i'm printing self before everything else so even if there's an error, i should be notified
let me check again
@commands.slash_command(dm_permission=False)
@commands.default_member_permissions(administrator=True)
async def source(self, inter):
print("source", self)
inter.self = self
pass
@source.sub_command_group()
async def channel(self, inter):
print("channel", self)
pass
@channel.sub_command()
async def show(self, inter):
"""
Show all source channels.
"""
print("show", self)
# self = inter.self
# await inter.response.defer(ephemeral=True)
# guild = await self.guilds_db.find_one({'_id': str(inter.guild.id)})
# if not guild:
# return await inter.followup.send('You must `/configure` your server first.', ephemeral=True)
# index_embed = disnake.Embed(
# title='**Source Channels**', description="", color=self.color)
# channels = []
# for channel_id in guild['channels']:
# channel = self.bot.get_channel(int(channel_id))
# if channel:
# channels.append(channel.mention)
# if len(channels) > 0:
# index_embed.description = "\n".join(channels)
# else:
# index_embed.description = "None."
# await inter.followup.send(embed=index_embed)
still printing None
Yeah, that is super weird.
source <__main__.Cog object at 0x000002B8DB6BED90>
channel <__main__.Cog object at 0x000002B8DB6BED90>
show <__main__.Cog object at 0x000002B8DB6BED90>
What disnake version?
I think that was asked already, though
@commands.slash_command(dm_permission=False)
@commands.default_member_permissions(administrator=True)
async def source(self, inter):
print("source", self)
inter.self = self
pass
@source.sub_command_group()
async def channel(self, inter):
print("channel", self)
pass
@channel.sub_command()
async def test(self, inter):
print("test", self)
pass
@channel.sub_command()
async def show(self, inter):
"""
Show all source channels.
"""
print("show", self)
# self = inter.self
# await inter.response.defer(ephemeral=True)
# guild = await self.guilds_db.find_one({'_id': str(inter.guild.id)})
# if not guild:
# return await inter.followup.send('You must `/configure` your server first.', ephemeral=True)
# index_embed = disnake.Embed(
# title='**Source Channels**', description="", color=self.color)
# channels = []
# for channel_id in guild['channels']:
# channel = self.bot.get_channel(int(channel_id))
# if channel:
# channels.append(channel.mention)
# if len(channels) > 0:
# index_embed.description = "\n".join(channels)
# else:
# index_embed.description = "None."
# await inter.followup.send(embed=index_embed)
adding new subcommand, test, works
disnake==2.9.0
changed the name= parameter and it fixed it, will keep testing and let you know if it breaks
It almost seems like it's a sync issue. You make a change, the command resyncs and it works, until something breaks it.
Because it worked temporarily after the last change which would have forced a resync.
It looks to me like they had something in the class namespace of the same name as the function
If you remember, methods are wrapped in descriptors, and descriptors outside classes receive None as the instance, which is then passed as self to the function
Which results in disnake holding a reference to the function but the class itself doesn't since it's overwritten
I think this is the issue, having multiple methods with same name, which is why changing function name and adding the name parameter worked