aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Leon Sandøy <[email protected]>2020-05-31 19:17:07 +0200
committerGravatar Leon Sandøy <[email protected]>2020-05-31 19:17:07 +0200
commit876b4846f612fe0011cc2e0b498b4df9e54d74cb (patch)
treea08d26932f1efd8a35e8a92ccba18375137c925e
parentMerge pull request #973 from python-discord/kwzrd/improve-free (diff)
Add support for bool values in RedisCache
We're gonna need this for the help channel handling, and it seems like a reasonable type to support anyway. It requires a tiny bit of special handling, but nothing outrageous.
-rw-r--r--bot/utils/redis_cache.py14
-rw-r--r--tests/bot/utils/test_redis_cache.py4
2 files changed, 15 insertions, 3 deletions
diff --git a/bot/utils/redis_cache.py b/bot/utils/redis_cache.py
index de80cee84..2926e7a89 100644
--- a/bot/utils/redis_cache.py
+++ b/bot/utils/redis_cache.py
@@ -2,6 +2,7 @@ from __future__ import annotations
import asyncio
import logging
+from distutils.util import strtobool
from functools import partialmethod
from typing import Any, Dict, ItemsView, Optional, Tuple, Union
@@ -11,7 +12,7 @@ log = logging.getLogger(__name__)
# Type aliases
RedisKeyType = Union[str, int]
-RedisValueType = Union[str, int, float]
+RedisValueType = Union[str, int, float, bool]
RedisKeyOrValue = Union[RedisKeyType, RedisValueType]
# Prefix tuples
@@ -20,6 +21,7 @@ _VALUE_PREFIXES = (
("f|", float),
("i|", int),
("s|", str),
+ ("b|", bool),
)
_KEY_PREFIXES = (
("i|", int),
@@ -117,7 +119,8 @@ class RedisCache:
def _to_typestring(key_or_value: RedisKeyOrValue, prefixes: _PrefixTuple) -> str:
"""Turn a valid Redis type into a typestring."""
for prefix, _type in prefixes:
- if isinstance(key_or_value, _type):
+ # isinstance is a bad idea here, because isintance(False, int) == True.
+ if type(key_or_value) is _type:
return f"{prefix}{key_or_value}"
raise TypeError(f"RedisCache._to_typestring only supports the following: {prefixes}.")
@@ -131,6 +134,13 @@ class RedisCache:
# Now we convert our unicode string back into the type it originally was.
for prefix, _type in prefixes:
if key_or_value.startswith(prefix):
+
+ # For booleans, we need special handling because bool("False") is True.
+ if prefix == "b|":
+ value = key_or_value[len(prefix):]
+ return bool(strtobool(value))
+
+ # Otherwise we can just convert normally.
return _type(key_or_value[len(prefix):])
raise TypeError(f"RedisCache._from_typestring only supports the following: {prefixes}.")
diff --git a/tests/bot/utils/test_redis_cache.py b/tests/bot/utils/test_redis_cache.py
index 8c1a40640..62c411681 100644
--- a/tests/bot/utils/test_redis_cache.py
+++ b/tests/bot/utils/test_redis_cache.py
@@ -59,7 +59,9 @@ class RedisCacheTests(unittest.IsolatedAsyncioTestCase):
test_cases = (
('favorite_fruit', 'melon'),
('favorite_number', 86),
- ('favorite_fraction', 86.54)
+ ('favorite_fraction', 86.54),
+ ('favorite_boolean', False),
+ ('other_boolean', True),
)
# Test that we can get and set different types.