diff options
-rw-r--r-- | botcore/utils/cooldown.py | 8 | ||||
-rw-r--r-- | tests/botcore/utils/test_cooldown.py | 26 |
2 files changed, 20 insertions, 14 deletions
diff --git a/botcore/utils/cooldown.py b/botcore/utils/cooldown.py index 099edba0..b9149b48 100644 --- a/botcore/utils/cooldown.py +++ b/botcore/utils/cooldown.py @@ -20,6 +20,8 @@ from botcore.utils.function import command_wraps __all__ = ["CommandOnCooldown", "block_duplicate_invocations", "P", "R"] +_KEYWORD_SEP_SENTINEL = object() + _ArgsList = list[object] _HashableArgsTuple = tuple[Hashable, ...] @@ -172,6 +174,10 @@ class _CommandCooldownManager: self._cooldowns[key] = filtered_cooldowns +def _create_argument_tuple(*args: object, **kwargs: object) -> Iterable[object]: + return (*args, _KEYWORD_SEP_SENTINEL, *kwargs.items()) + + def block_duplicate_invocations( *, cooldown_duration: float = 5, send_notice: bool = False ) -> Callable[[Callable[P, Awaitable[R]]], Callable[P, Awaitable[R]]]: @@ -194,7 +200,7 @@ def block_duplicate_invocations( @command_wraps(func) async def wrapper(*args: P.args, **kwargs: P.kwargs) -> R: - arg_tuple = (*args[2:], *kwargs.items()) # skip self and ctx from the command + arg_tuple = _create_argument_tuple(*args[2:], **kwargs) # skip self and ctx from the command ctx = typing.cast("Context[BotBase]", args[1]) channel = ctx.channel diff --git a/tests/botcore/utils/test_cooldown.py b/tests/botcore/utils/test_cooldown.py index 87c433ce..00e5a052 100644 --- a/tests/botcore/utils/test_cooldown.py +++ b/tests/botcore/utils/test_cooldown.py @@ -1,23 +1,18 @@ import unittest -from collections.abc import Iterable from unittest.mock import patch -from botcore.utils.cooldown import _CommandCooldownManager - - -def create_argument_tuple(*args, **kwargs) -> Iterable[object]: - return (*args, *kwargs.items()) +from botcore.utils.cooldown import _CommandCooldownManager, _create_argument_tuple class CommandCooldownManagerTests(unittest.IsolatedAsyncioTestCase): test_call_args = ( - create_argument_tuple(0), - create_argument_tuple(a=0), - create_argument_tuple([]), - create_argument_tuple(a=[]), - create_argument_tuple(1, 2, 3, a=4, b=5, c=6), - create_argument_tuple([1], [2], [3], a=[4], b=[5], c=[6]), - create_argument_tuple([1], 2, [3], a=4, b=[5], c=6), + _create_argument_tuple(0), + _create_argument_tuple(a=0), + _create_argument_tuple([]), + _create_argument_tuple(a=[]), + _create_argument_tuple(1, 2, 3, a=4, b=5, c=6), + _create_argument_tuple([1], [2], [3], a=[4], b=[5], c=[6]), + _create_argument_tuple([1], 2, [3], a=4, b=[5], c=6), ) async def asyncSetUp(self): @@ -47,3 +42,8 @@ class CommandCooldownManagerTests(unittest.IsolatedAsyncioTestCase): with self.subTest(arguments_tuple=call_args): self.cooldown_manager.set_cooldown(0, call_args) self.assertFalse(self.cooldown_manager.is_on_cooldown(0, call_args)) + + def test_keywords_and_tuples_differentiated(self): + self.cooldown_manager.set_cooldown(0, _create_argument_tuple(("a", 0))) + self.assertFalse(self.cooldown_manager.is_on_cooldown(0, _create_argument_tuple(a=0))) + self.assertTrue(self.cooldown_manager.is_on_cooldown(0, _create_argument_tuple(("a", 0)))) |