diff --git a/README.md b/README.md index 068c9e4..ad822ff 100644 --- a/README.md +++ b/README.md @@ -2,20 +2,22 @@ redis-simple-cache is a pythonic interface for creating a cache over redis. It provides simple decorators that can be added to any function to cache its return values. +Forked package with python 3 support. +Original package is located here: https://github.com/vivekn/redis-simple-cache + Requirements: ------------- -redis 2.6.2 -redis-py 2.7.1 (see requirements.txt file) +redis 4.0.0 Installation: ------------- - pip install redis-simple-cache + pip install redis-simple-cache-3k or to get the latest version - git clone git://github.com/vivekn/redis-simple-cache.git - cd redis-simple-cache + git clone git://github.com/ohanetz/redis-simple-cache-3k.git + cd redis-simple-cache-3k python setup.py install Usage: @@ -88,4 +90,7 @@ Robert Marshall Ben Hayden + +Python 3 and Redis 4 support added by Omer Hanetz + LICENSE: BSD diff --git a/redis_cache/__init__.py b/redis_cache/__init__.py index a46e94e..ce5d31b 100644 --- a/redis_cache/__init__.py +++ b/redis_cache/__init__.py @@ -1 +1 @@ -from rediscache import * \ No newline at end of file +from .rediscache import * diff --git a/redis_cache/rediscache.py b/redis_cache/rediscache.py index f951bd8..6fca34b 100644 --- a/redis_cache/rediscache.py +++ b/redis_cache/rediscache.py @@ -7,6 +7,11 @@ import hashlib import redis import logging +import sys + +if sys.version_info[0] >= 3: # Maintain support for python 2.x + basestring = str + unicode = str DEFAULT_EXPIRY = 60 * 60 * 24 @@ -17,11 +22,13 @@ class RedisConnect(object): This makes the Simple Cache class a little more flexible, for cases where redis connection configuration needs customizing. """ - def __init__(self, host=None, port=None, db=None, password=None): + def __init__(self, host=None, port=None, db=None, password=None, decode_responses=True, encoding='iso-8859-1'): self.host = host if host else 'localhost' self.port = port if port else 6379 self.db = db if db else 0 self.password = password + self.decode_responses = decode_responses + self.encoding = encoding def connect(self): """ @@ -40,7 +47,9 @@ def connect(self): return redis.StrictRedis(host=self.host, port=self.port, db=self.db, - password=self.password) + password=self.password, + decode_responses=self.decode_responses, + encoding=self.encoding) class CacheMissException(Exception): @@ -76,7 +85,9 @@ def __init__(self, port=None, db=None, password=None, - namespace="SimpleCache"): + namespace="SimpleCache", + decode_responses=True, + encoding='iso-8859-1'): self.limit = limit # No of json encoded strings to cache self.expire = expire # Time to keys to expire in seconds @@ -89,8 +100,10 @@ def __init__(self, self.connection = RedisConnect(host=self.host, port=self.port, db=self.db, - password=password).connect() - except RedisNoConnException, e: + password=password, + decode_responses=decode_responses, + encoding=encoding).connect() + except RedisNoConnException: self.connection = None pass @@ -232,8 +245,8 @@ def mget(self, keys): def get_json(self, key): return json.loads(self.get(key)) - def get_pickle(self, key): - return pickle.loads(self.get(key)) + def get_pickle(self, key, encoding='iso-8859-1'): + return pickle.loads(self.get(key).encode(encoding)) def mget_json(self, keys): """ @@ -276,7 +289,6 @@ def __len__(self): def keys(self): return self.connection.smembers(self.get_set_name()) - def flush(self): keys = list(self.keys()) keys.append(self.get_set_name()) @@ -290,12 +302,12 @@ def flush_namespace(self, space): keys = list(self.connection.keys(namespace)) with self.connection.pipeline() as pipe: pipe.delete(*keys) - pipe.srem(setname, *space) + pipe.srem(setname, *[key for key in self.keys() if key[:key.find(':')] == space]) pipe.execute() def get_hash(self, args): if self.hashkeys: - key = hashlib.md5(args).hexdigest() + key = hashlib.md5(args.encode('utf-8')).hexdigest() else: key = pickle.dumps(args) return key @@ -365,7 +377,6 @@ def func(*args, **kwargs): return decorator - def cache_it_json(limit=10000, expire=DEFAULT_EXPIRY, cache=None, namespace=None): """ Arguments and function result must be able to convert to JSON. diff --git a/redis_cache/test_rediscache.py b/redis_cache/test_rediscache.py index f961d8c..9587fc7 100644 --- a/redis_cache/test_rediscache.py +++ b/redis_cache/test_rediscache.py @@ -1,10 +1,11 @@ -#SimpleCache Tests -#~~~~~~~~~~~~~~~~~~~ +# SimpleCache Tests +# ~~~~~~~~~~~~~~~~~~~ from datetime import timedelta -from rediscache import SimpleCache, RedisConnect, cache_it, cache_it_json, CacheMissException, ExpiredKeyException, DoNotCache +from redis_cache.rediscache import SimpleCache, RedisConnect, cache_it, cache_it_json, CacheMissException, ExpiredKeyException, DoNotCache from unittest import TestCase, main import time + class ComplexNumber(object): # used in pickle test def __init__(self, real, imag): self.real = real @@ -20,6 +21,7 @@ def setUp(self): self.c = SimpleCache(10) # Cache that has a maximum limit of 10 keys self.assertIsNotNone(self.c.connection) self.redis = RedisConnect().connect() + def test_expire(self): quick_c = SimpleCache() @@ -189,7 +191,7 @@ def test_flush(self): connection.delete("will_not_be_deleted") def test_flush_namespace(self): - self.redis.flushall() + self.redis.flushall() self.c.store("foo:one", "bir") self.c.store("foo:two", "bor") self.c.store("fii", "bur") @@ -295,4 +297,6 @@ def test_invalidate_key(self): def tearDown(self): self.c.flush() + main() + diff --git a/requirements.txt b/requirements.txt index 61a87b2..d487736 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1 @@ -redis>=2.7.1 +redis>=4.0.0 diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..b88034e --- /dev/null +++ b/setup.cfg @@ -0,0 +1,2 @@ +[metadata] +description-file = README.md diff --git a/setup.py b/setup.py index ac2a2ea..9c748a4 100644 --- a/setup.py +++ b/setup.py @@ -6,17 +6,18 @@ def openf(fname): return open(os.path.join(os.path.dirname(__file__), fname)) setup( - name="redis-simple-cache", - version="0.0.6", - author="Vivek Narayanan, Flávio Juvenal, Sam Zaydel", + name="redis-simple-cache-3k", + version="0.0.7", + author="Vivek Narayanan, Flávio Juvenal, Sam Zaydel. Python 3 and Redis 4 support by Omer Hanetz", author_email="flaviojuvenal@gmail.com", description="redis-simple-cache is a pythonic interface for creating a cache over redis. " "It provides simple decorators that can be added to any function to cache its return values. ", license="3-clause BSD", keywords="decorator decorators redis cache", - url="https://github.com/vivekn/redis-simple-cache", + url="https://github.com/ohanetz/redis-simple-cache-3k", packages=['redis_cache'], long_description=openf("README.md").read(), + long_description_content_type='text/markdown', install_requires=[line.strip() for line in openf("requirements.txt") if line.strip()], classifiers=[ "Development Status :: 3 - Alpha",