aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--botcore/utils/cooldown.py8
-rw-r--r--tests/botcore/utils/test_cooldown.py26
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))))