Skip to content

Instantly share code, notes, and snippets.

@Ikusaba-san
Created October 17, 2017 00:32
Show Gist options
  • Save Ikusaba-san/dbf3042efbd2436fc83de98c161d4a37 to your computer and use it in GitHub Desktop.
Save Ikusaba-san/dbf3042efbd2436fc83de98c161d4a37 to your computer and use it in GitHub Desktop.
A superclass for all my cogs
import inspect
import re
def _get_name_mangled_attrs(cls, attr):
for c in cls.__mro__:
try:
yield getattr(c, f'_{c.__name__}__{attr}')
except AttributeError:
continue
async def _async_all(iterable, isawaitable=inspect.isawaitable):
for elem in iterable:
if isawaitable(elem):
elem = await elem
if not elem:
return False
return True
class Cog:
def __init__(self, bot):
self.bot = bot
def __init_subclass__(cls, *, name=None, **kwargs):
super().__init_subclass__(**kwargs)
cls_name = cls.__name__
name = name or cls_name
cls.name = re.sub(r"(\w)([A-Z])", r"\1 \2", name)
# Set the local/global checks
for check in ('local_check', 'global_check', 'global_check_once'):
checks = list(_get_name_mangled_attrs(cls, check))
if not checks:
# Don't waste space and time processing no checks.
continue
if len(checks) == 1:
# Shortcut to save a for-loop and function call for each time
# the check is processed
check = check[0]
else:
async def check(self, ctx, checks=checks):
return await _async_all(c(self, ctx) for c in checks)
# cls.__attr uses the base class's name, so we have to use setattr
setattr(cls, f'_{cls_name}__{check}', check)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment