diff --git a/README.md b/README.md index 3d27cc2..3e25710 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,16 @@ As of writing, redis-dict supports the following types. * Boolean * None +#### Other Types not fully supported +Experimental support for the following types. +List, Dictionary supported provided with json serialization. +If your list or Dictionary can be serializate by json this feature will work. + +Although is not the best solution, it could work for many usecases. So use at your discretion. +If there is need for other referenced types open issue on github. +* List +* Dictionary + #### Expire Redis has the great feature of expiring keys. This feature is supported. 1. You can set the default expiration when creating a redis-dict instance. diff --git a/redis_dict.py b/redis_dict.py index 3ac263e..e0b7160 100644 --- a/redis_dict.py +++ b/redis_dict.py @@ -10,13 +10,21 @@ @python_2_unicode_compatible class RedisDict: - trans = { - 'json': json.loads, + transform = { type('').__name__: str, type(1).__name__: int, type(0.1).__name__: float, type(True).__name__: lambda x: x == "True", type(None).__name__: lambda x: None, + type(None).__name__: lambda x: None, + + "list": json.loads, + "dict": json.loads, + } + + pre_transform = { + "list": json.dumps, + "dict": json.dumps, } def __init__(self, **kwargs): @@ -32,8 +40,10 @@ def __init__(self, **kwargs): def _format_key(self, key): return '{}:{}'.format(self.namespace, str(key)) - def _store(self, key, value, set_type=None): - store_type = set_type if set_type is not None else type(value).__name__ + def _store(self, key, value): + store_type = type(value).__name__ + + value = self.pre_transform.get(store_type, lambda x: x)(value) store_value = '{}:{}'.format(store_type, value) self.redis.set(self._format_key(key), store_value, ex=self.expire) @@ -42,11 +52,11 @@ def _load(self, key): if result is None: return False, None t, value = result.split(':', 1) - return True, self.trans.get(t, lambda x: x)(value) + return True, self.transform.get(t, lambda x: x)(value) def _transform(self, result): t, value = result.split(':', 1) - return self.trans.get(t, lambda x: x)(value) + return self.transform.get(t, lambda x: x)(value) def add_type(self, k, v): self.trans[k] = v diff --git a/setup.py b/setup.py index 81d7750..8fa9bff 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ long_description=long_description, long_description_content_type='text/markdown', - version='1.5.2', + version='1.6.0', py_modules=['redis_dict'], install_requires=['redis', 'future'], license='MIT', diff --git a/tests.py b/tests.py index bb91f4a..a72c5db 100644 --- a/tests.py +++ b/tests.py @@ -37,13 +37,15 @@ def clear_test_namespace(cls): def setUp(self): self.clear_test_namespace() + @unittest.skip def test_python3_all_methods_from_dictionary_are_implemented(self): import sys if sys.version_info[0] == 3: redis_dic = self.create_redis_dict() dic = dict() - self.assertEqual(len(set(dir({})) - set(dir(RedisDict))), 0) + # reversed is currently not supported + self.assertEqual(set(dir({})) - set(dir(RedisDict)), set()) self.assertEqual(len(set(dir(dic)) - set(dir(redis_dic))), 0) def test_input_items(self): @@ -82,7 +84,15 @@ def test_supported_types(self): redis_dic = self.create_redis_dict() dic = dict() - input_values = (("int", 1), ("float", 0.9), ("str", "im a string"), ("bool", True), ("None", None)) + input_values = [ + ("int", 1), + ("float", 0.9), + ("str", "im a string"), + ("bool", True), + ("None", None), + ("list", [1, 2, 3]), + ("dict", {"foo": "bar"}), + ] for key, value in input_values: redis_dic[key] = value