aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar MarkKoz <[email protected]>2019-09-26 18:25:04 -0700
committerGravatar MarkKoz <[email protected]>2019-10-01 18:25:30 -0700
commit689d203475cb68b1eb85afe6e44c688197c56a9b (patch)
tree470f097b0f0ac1744882c84419c4af5a237bb97a
parentMake respect_role_hierarchy a decorator (diff)
Support positional target arg for respect_role_hierarchy
* Add some logging
-rw-r--r--bot/decorators.py19
1 files changed, 16 insertions, 3 deletions
diff --git a/bot/decorators.py b/bot/decorators.py
index a44d62afa..d8a9494d2 100644
--- a/bot/decorators.py
+++ b/bot/decorators.py
@@ -3,7 +3,7 @@ import random
from asyncio import Lock, sleep
from contextlib import suppress
from functools import wraps
-from typing import Any, Callable, Container, Optional
+from typing import Any, Callable, Container, Optional, Union
from weakref import WeakValueDictionary
from discord import Colour, Embed, Member
@@ -144,20 +144,33 @@ def redirect_output(destination_channel: int, bypass_roles: Container[int] = Non
return wrap
-def respect_role_hierarchy(target_arg_name: str = "user") -> Callable:
+def respect_role_hierarchy(target_arg: Union[int, str] = 0) -> Callable:
"""
Ensure the highest role of the invoking member is greater than that of the target member.
If the condition fails, a warning is sent to the invoking context. A target which is not an
instance of discord.Member will always pass.
+ A value of 0 (i.e. position 0) for `target_arg` corresponds to the argument which comes after
+ `ctx`. If the target argument is a kwarg, its name can instead be given.
+
This decorator must go before (below) the `command` decorator.
"""
def wrap(func: Callable) -> Callable:
@wraps(func)
async def inner(self: Callable, ctx: Context, *args, **kwargs) -> Any:
- target = kwargs[target_arg_name]
+ try:
+ target = kwargs[target_arg]
+ except KeyError:
+ try:
+ target = args[target_arg]
+ except IndexError:
+ log.error(f"Could not find target member argument at position {target_arg}")
+ except TypeError:
+ log.error(f"Could not find target member kwarg with key {target_arg!r}")
+
if not isinstance(target, Member):
+ log.trace("The target is not a discord.Member; skipping role hierarchy check.")
return await func(self, ctx, *args, **kwargs)
cmd = ctx.command.name