import discord import discord.ext.commands as commands from functools import singledispatch class CheckFailDoNotNotify(commands.CheckFailure): """ A custom exception that we can raise inside command check functions if the check fails, but the global error handling should not notify the user about the error. For example it can be used if the check function already sent the user a customised error message. """ pass def is_administrator(member: discord.Member) -> bool: """ :return: Whether the given guild member has administrator powers """ return member.guild_permissions.administrator @singledispatch def to_string(obj) -> str: """ Convert the given discord object to a string, for logging purposes. See functools.singledispatch """ return str(obj) @to_string.register(discord.Object) @to_string.register(discord.abc.Snowflake) def _(obj) -> str: return f"<{obj.id}>" @to_string.register(discord.abc.User) def _(user) -> str: return f"{user.name}#{user.discriminator}({user.id})" @to_string.register(discord.Guild) def _(guild) -> str: return f"{guild.name}({guild.id})" # Even though these types are all subclasses of discord.abc.GuildChannel, it does not work if we register that class directly @to_string.register(discord.TextChannel) @to_string.register(discord.VoiceChannel) @to_string.register(discord.CategoryChannel) def _(channel) -> str: return f"{channel.name}({channel.id})" @to_string.register(discord.Role) def _(role) -> str: return f"@{role.name}({role.id})"