aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar MarkKoz <[email protected]>2020-07-17 11:06:17 -0700
committerGravatar MarkKoz <[email protected]>2020-07-31 22:58:05 -0700
commita16ba995944e213f90fbe78d2ec534f99f70b9f8 (patch)
tree32292c56a0edd3e9a2b6c7c9153b0f087d049122
parentDecorators: add mutually exclusive decorator (diff)
Decorators: drop arg pos/name support for mutually_exclusive
Supporting ID retrieval by arg name or position made for a confusing interface. I also doubt it would have been used much. A callable can achieve the same thing, albeit with a little more code. Now the decorator instead supports passing an ID directly or a callable.
-rw-r--r--bot/decorators.py19
1 files changed, 9 insertions, 10 deletions
diff --git a/bot/decorators.py b/bot/decorators.py
index cae0870b6..f49499856 100644
--- a/bot/decorators.py
+++ b/bot/decorators.py
@@ -17,7 +17,7 @@ log = logging.getLogger(__name__)
__lock_dicts = defaultdict(WeakValueDictionary)
Argument = t.Union[int, str]
-ResourceId = t.Union[Argument, t.Callable[..., t.Hashable]]
+ResourceId = t.Union[t.Hashable, t.Callable[..., t.Hashable]]
def in_whitelist(
@@ -95,28 +95,27 @@ def locked() -> t.Callable:
return wrap
-def mutually_exclusive(namespace: t.Hashable, resource_arg: ResourceId) -> t.Callable:
+def mutually_exclusive(namespace: t.Hashable, resource_id: ResourceId) -> t.Callable:
"""
- Turn the decorated coroutine function into a mutually exclusive operation on a resource.
+ Turn the decorated coroutine function into a mutually exclusive operation on a `resource_id`.
If any other mutually exclusive function currently holds the lock for a resource, do not run the
decorated function and return None.
`namespace` is an identifier used to prevent collisions among resource IDs.
- `resource_arg` is the positional index or name of the parameter of the decorated function whose
- value will be the resource ID. It may also be a callable which will return the resource ID
- given the decorated function's args and kwargs.
+ `resource_id` identifies a resource on which to perform a mutually exclusive operation. It may
+ also be a callable which will return the resource ID given the decorated function's args and
+ kwargs.
"""
def decorator(func: t.Callable) -> t.Callable:
@wraps(func)
async def wrapper(*args, **kwargs) -> t.Any:
- if callable(resource_arg):
+ if callable(resource_id):
# Call to get the ID if a callable was given.
- id_ = resource_arg(*args, **kwargs)
+ id_ = resource_id(*args, **kwargs)
else:
- # Retrieve the ID from the args via position or name.
- id_ = _get_arg_value(resource_arg, args, kwargs)
+ id_ = resource_id
# Get the lock for the ID. Create a Lock if one doesn't exist yet.
locks = __lock_dicts[namespace]