diff options
author | 2020-05-24 10:54:34 +0200 | |
---|---|---|
committer | 2020-05-24 10:54:34 +0200 | |
commit | 1d05a4d409cd0652cec36128114739ede2f529cf (patch) | |
tree | e560dcfaba960cb0662debbe56de8d62fcf76fd6 | |
parent | Refactor the nice prefix/type strings to constants (diff) |
Improves various docstrings and comments.
Thanks to @MarkKoz for suggesting most of these in their code review.
-rw-r--r-- | bot/utils/redis_cache.py | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/bot/utils/redis_cache.py b/bot/utils/redis_cache.py index d5563c079..e4dce7526 100644 --- a/bot/utils/redis_cache.py +++ b/bot/utils/redis_cache.py @@ -24,14 +24,6 @@ class RedisCache: """ A simplified interface for a Redis connection. - This class must be created as a class attribute in a class. This is because it - uses __set_name__ to create a namespace like MyCog.my_class_attribute which is - used as a hash name when we store stuff in Redis, to prevent collisions. - - The class this object is instantiated in must also contains an attribute with an - instance of Bot. This is because Bot contains our redis_pool, which is how this - class communicates with the Redis server. - We implement several convenient methods that are fairly similar to have a dict behaves, and should be familiar to Python users. The biggest difference is that all the public methods in this class are coroutines, and must be awaited. @@ -39,6 +31,10 @@ class RedisCache: Because of limitations in Redis, this cache will only accept strings, integers and floats both for keys and values. + Please note that this class MUST be created as a class attribute, and that that class + must also contain an attribute with an instance of our Bot. See `__get__` and `__set_name__` + for more information about how this works. + Simple example for how to use this: class SomeCog(Cog): @@ -78,12 +74,18 @@ class RedisCache: _namespaces = [] def __init__(self) -> None: - """Raise a NotImplementedError if `__set_name__` hasn't been run.""" + """Initialize the RedisCache.""" self._namespace = None self.bot = None def _set_namespace(self, namespace: str) -> None: """Try to set the namespace, but do not permit collisions.""" + # We need a unique namespace, to prevent collisions. This loop + # will try appending underscores to the end of the namespace until + # it finds one that is unique. + # + # For example, if `john` and `john_` are both taken, the namespace will + # be `john__` at the end of this loop. while namespace in self._namespaces: namespace += "_" @@ -136,11 +138,26 @@ class RedisCache: Set the namespace to Class.attribute_name. Called automatically when this class is constructed inside a class as an attribute. + + This class MUST be created as a class attribute in a class, otherwise it will raise + exceptions whenever a method is used. This is because it uses this method to create + a namespace like `MyCog.my_class_attribute` which is used as a hash name when we store + stuff in Redis, to prevent collisions. """ self._set_namespace(f"{owner.__name__}.{attribute_name}") def __get__(self, instance: RedisCache, owner: Any) -> RedisCache: - """Fetch the Bot instance, we need it for the redis pool.""" + """ + This is called if the RedisCache is a class attribute, and is accessed. + + The class this object is instantiated in must contain an attribute with an + instance of Bot. This is because Bot contains our redis_session, which is + the mechanism by which we will communicate with the Redis server. + + Any attempt to use RedisCache in a class that does not have a Bot instance + will fail. It is mostly intended to be used inside of a Cog, although theoretically + it should work in any class that has a Bot instance. + """ if self.bot: return self |