From e95903c73ec5c255fb6c930e0838ab336eedd056 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Jim=C3=A9nez?= Date: Fri, 3 Nov 2017 23:42:17 +0100 Subject: [PATCH 1/4] Add Python 3 compatibility --- redis_cache/__init__.py | 2 +- redis_cache/rediscache.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/redis_cache/__init__.py b/redis_cache/__init__.py index a46e94e..c186c2c 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 * \ No newline at end of file diff --git a/redis_cache/rediscache.py b/redis_cache/rediscache.py index f951bd8..f720d28 100644 --- a/redis_cache/rediscache.py +++ b/redis_cache/rediscache.py @@ -8,6 +8,8 @@ import redis import logging +from redis._compat import basestring, unicode + DEFAULT_EXPIRY = 60 * 60 * 24 @@ -90,7 +92,7 @@ def __init__(self, port=self.port, db=self.db, password=password).connect() - except RedisNoConnException, e: + except RedisNoConnException as e: self.connection = None pass From c6bffe23cd923408ff678bdbf9579e67bfc0ef36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Jim=C3=A9nez?= Date: Tue, 14 Nov 2017 15:48:31 +0100 Subject: [PATCH 2/4] Updated to a fixed redis version --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 61a87b2..2318a9f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1 @@ -redis>=2.7.1 +redis==2.10.5 From 4577d4836c0f41f48171281c322bc7228bd9c725 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Jim=C3=A9nez?= Date: Tue, 5 Mar 2019 12:00:15 +0100 Subject: [PATCH 3/4] Update to the new redis version --- Pipfile | 13 ++++++ Pipfile.lock | 81 ++++++++++++++++++++++++++++++++++ redis_cache/rediscache.py | 6 ++- redis_cache/test_rediscache.py | 34 +++++++++----- requirements.txt | 2 +- 5 files changed, 121 insertions(+), 15 deletions(-) create mode 100644 Pipfile create mode 100644 Pipfile.lock diff --git a/Pipfile b/Pipfile new file mode 100644 index 0000000..d0cc00f --- /dev/null +++ b/Pipfile @@ -0,0 +1,13 @@ +[[source]] +url = "https://pypi.org/simple" +verify_ssl = true +name = "pypi" + +[dev-packages] +pytest = "*" + +[packages] +redis = "*" + +[requires] +python_version = "3.6" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 0000000..3db7bea --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,81 @@ +{ + "_meta": { + "hash": { + "sha256": "713fb3ff01f3b63d03215509171090a5cbd1b763be05402d631a1e3d97248daf" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.6" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "redis": { + "hashes": [ + "sha256:724932360d48e5407e8f82e405ab3650a36ed02c7e460d1e6fddf0f038422b54", + "sha256:9b19425a38fd074eb5795ff2b0d9a55b46a44f91f5347995f27e3ad257a7d775" + ], + "index": "pypi", + "version": "==3.2.0" + } + }, + "develop": { + "atomicwrites": { + "hashes": [ + "sha256:03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4", + "sha256:75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6" + ], + "version": "==1.3.0" + }, + "attrs": { + "hashes": [ + "sha256:69c0dbf2ed392de1cb5ec704444b08a5ef81680a61cb899dc08127123af36a79", + "sha256:f0b870f674851ecbfbbbd364d6b5cbdff9dcedbc7f3f5e18a6891057f21fe399" + ], + "version": "==19.1.0" + }, + "more-itertools": { + "hashes": [ + "sha256:0125e8f60e9e031347105eb1682cef932f5e97d7b9a1a28d9bf00c22a5daef40", + "sha256:590044e3942351a1bdb1de960b739ff4ce277960f2425ad4509446dbace8d9d1" + ], + "markers": "python_version > '2.7'", + "version": "==6.0.0" + }, + "pluggy": { + "hashes": [ + "sha256:19ecf9ce9db2fce065a7a0586e07cfb4ac8614fe96edf628a264b1c70116cf8f", + "sha256:84d306a647cc805219916e62aab89caa97a33a1dd8c342e87a37f91073cd4746" + ], + "version": "==0.9.0" + }, + "py": { + "hashes": [ + "sha256:64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa", + "sha256:dc639b046a6e2cff5bbe40194ad65936d6ba360b52b3c3fe1d08a82dd50b5e53" + ], + "version": "==1.8.0" + }, + "pytest": { + "hashes": [ + "sha256:067a1d4bf827ffdd56ad21bd46674703fce77c5957f6c1eef731f6146bfcef1c", + "sha256:9687049d53695ad45cf5fdc7bbd51f0c49f1ea3ecfc4b7f3fde7501b541f17f4" + ], + "index": "pypi", + "version": "==4.3.0" + }, + "six": { + "hashes": [ + "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", + "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" + ], + "version": "==1.12.0" + } + } +} diff --git a/redis_cache/rediscache.py b/redis_cache/rediscache.py index f720d28..eaa03b0 100644 --- a/redis_cache/rediscache.py +++ b/redis_cache/rediscache.py @@ -42,7 +42,9 @@ def connect(self): return redis.StrictRedis(host=self.host, port=self.port, db=self.db, - password=self.password) + password=self.password, + charset="iso-8859-1", + decode_responses=True) class CacheMissException(Exception): @@ -235,7 +237,7 @@ def get_json(self, key): return json.loads(self.get(key)) def get_pickle(self, key): - return pickle.loads(self.get(key)) + return pickle.loads(self.get(key).encode("iso-8859-1")) def mget_json(self, keys): """ diff --git a/redis_cache/test_rediscache.py b/redis_cache/test_rediscache.py index f961d8c..f40e880 100644 --- a/redis_cache/test_rediscache.py +++ b/redis_cache/test_rediscache.py @@ -1,10 +1,15 @@ -#SimpleCache Tests -#~~~~~~~~~~~~~~~~~~~ +# SimpleCache Tests +# ~~~~~~~~~~~~~~~~~~~ from datetime import timedelta -from rediscache import SimpleCache, RedisConnect, cache_it, cache_it_json, CacheMissException, ExpiredKeyException, DoNotCache -from unittest import TestCase, main + +import pytest + +from rediscache import SimpleCache, RedisConnect, cache_it, cache_it_json, CacheMissException, ExpiredKeyException, \ + DoNotCache +from unittest import TestCase import time + class ComplexNumber(object): # used in pickle test def __init__(self, real, imag): self.real = real @@ -14,12 +19,13 @@ def __eq__(self, other): return self.real == other.real and self.imag == other.imag -class SimpleCacheTest(TestCase): +class TestSimpleCache(TestCase): 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() @@ -40,6 +46,7 @@ def test_kwargs_decorator(self): @cache_it_json(cache=self.c) def add_it(a, b=10, c=5): return a + b + c + add_it(3) self.assertEqual(add_it(3), 18) add_it(5, b=7) @@ -58,17 +65,19 @@ def test_json(self): self.assertEqual(self.c.get_json("json"), payload) def test_pickle(self): - payload = ComplexNumber(3,4) + payload = ComplexNumber(3, 4) self.c.store_pickle("pickle", payload) self.assertEqual(self.c.get_pickle("pickle"), payload) def test_decorator(self): self.redis.flushall() mutable = [] + @cache_it(cache=self.c) def append(n): mutable.append(n) return mutable + append(1) len_before = len(mutable) mutable_cached = append(1) @@ -142,10 +151,12 @@ def test_decorator_json(self): import random mutable = {} + @cache_it_json(cache=self.c) def set_key(n): mutable[str(random.random())] = n return mutable + set_key('a') len_before = len(mutable) mutable_cached = set_key('a') @@ -160,11 +171,12 @@ def test_decorator_complex_type(self): @cache_it(cache=self.c) def add(x, y): return ComplexNumber(x.real + y.real, x.imag + y.imag) - result = add(ComplexNumber(3,4), ComplexNumber(4,5)) - result_cached = add(ComplexNumber(3,4), ComplexNumber(4,5)) + + result = add(ComplexNumber(3, 4), ComplexNumber(4, 5)) + result_cached = add(ComplexNumber(3, 4), ComplexNumber(4, 5)) self.assertNotEqual(id(result), id(result_cached)) self.assertEqual(result, result_cached) - self.assertEqual(result, complex(3,4) + complex(4,5)) + self.assertEqual(result, complex(3, 4) + complex(4, 5)) def test_cache_limit(self): for i in range(100): @@ -189,7 +201,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") @@ -294,5 +306,3 @@ def test_invalidate_key(self): def tearDown(self): self.c.flush() - -main() diff --git a/requirements.txt b/requirements.txt index 2318a9f..172fe9c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1 @@ -redis==2.10.5 +redis==3.2.0 From 299ad5e51d8982cd0f3c7767094edf9ceb94aa9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Jim=C3=A9nez?= Date: Sun, 19 Jan 2020 13:50:10 +0100 Subject: [PATCH 4/4] Replace pipenv by poetry --- .gitignore | 2 ++ Pipfile | 13 ------- Pipfile.lock | 81 ----------------------------------------- poetry.lock | 93 ++++++++++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 19 ++++++++++ requirements.txt | 1 - setup.py | 26 -------------- 7 files changed, 114 insertions(+), 121 deletions(-) delete mode 100644 Pipfile delete mode 100644 Pipfile.lock create mode 100644 poetry.lock create mode 100644 pyproject.toml delete mode 100644 requirements.txt delete mode 100644 setup.py diff --git a/.gitignore b/.gitignore index 6155e5f..1c96ffd 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ *.idea .DS_Store *.rdb + +dist/ diff --git a/Pipfile b/Pipfile deleted file mode 100644 index d0cc00f..0000000 --- a/Pipfile +++ /dev/null @@ -1,13 +0,0 @@ -[[source]] -url = "https://pypi.org/simple" -verify_ssl = true -name = "pypi" - -[dev-packages] -pytest = "*" - -[packages] -redis = "*" - -[requires] -python_version = "3.6" diff --git a/Pipfile.lock b/Pipfile.lock deleted file mode 100644 index 3db7bea..0000000 --- a/Pipfile.lock +++ /dev/null @@ -1,81 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "713fb3ff01f3b63d03215509171090a5cbd1b763be05402d631a1e3d97248daf" - }, - "pipfile-spec": 6, - "requires": { - "python_version": "3.6" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.org/simple", - "verify_ssl": true - } - ] - }, - "default": { - "redis": { - "hashes": [ - "sha256:724932360d48e5407e8f82e405ab3650a36ed02c7e460d1e6fddf0f038422b54", - "sha256:9b19425a38fd074eb5795ff2b0d9a55b46a44f91f5347995f27e3ad257a7d775" - ], - "index": "pypi", - "version": "==3.2.0" - } - }, - "develop": { - "atomicwrites": { - "hashes": [ - "sha256:03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4", - "sha256:75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6" - ], - "version": "==1.3.0" - }, - "attrs": { - "hashes": [ - "sha256:69c0dbf2ed392de1cb5ec704444b08a5ef81680a61cb899dc08127123af36a79", - "sha256:f0b870f674851ecbfbbbd364d6b5cbdff9dcedbc7f3f5e18a6891057f21fe399" - ], - "version": "==19.1.0" - }, - "more-itertools": { - "hashes": [ - "sha256:0125e8f60e9e031347105eb1682cef932f5e97d7b9a1a28d9bf00c22a5daef40", - "sha256:590044e3942351a1bdb1de960b739ff4ce277960f2425ad4509446dbace8d9d1" - ], - "markers": "python_version > '2.7'", - "version": "==6.0.0" - }, - "pluggy": { - "hashes": [ - "sha256:19ecf9ce9db2fce065a7a0586e07cfb4ac8614fe96edf628a264b1c70116cf8f", - "sha256:84d306a647cc805219916e62aab89caa97a33a1dd8c342e87a37f91073cd4746" - ], - "version": "==0.9.0" - }, - "py": { - "hashes": [ - "sha256:64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa", - "sha256:dc639b046a6e2cff5bbe40194ad65936d6ba360b52b3c3fe1d08a82dd50b5e53" - ], - "version": "==1.8.0" - }, - "pytest": { - "hashes": [ - "sha256:067a1d4bf827ffdd56ad21bd46674703fce77c5957f6c1eef731f6146bfcef1c", - "sha256:9687049d53695ad45cf5fdc7bbd51f0c49f1ea3ecfc4b7f3fde7501b541f17f4" - ], - "index": "pypi", - "version": "==4.3.0" - }, - "six": { - "hashes": [ - "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", - "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" - ], - "version": "==1.12.0" - } - } -} diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..aebd322 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,93 @@ +[[package]] +category = "main" +description = "Cryptographic modules for Python." +name = "pycrypto" +optional = false +python-versions = "*" +version = "2.6.1" + +[[package]] +category = "main" +description = "Lock context manager implemented via redis SETNX/BLPOP." +name = "python-redis-lock" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "3.5.0" + +[package.dependencies] +redis = ">=2.10.0" + +[package.extras] +django = ["django-redis (>=3.8.0)"] + +[[package]] +category = "main" +description = "Python client for Redis key-value store" +name = "redis" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "3.3.11" + +[package.extras] +hiredis = ["hiredis (>=0.1.3)"] + +[[package]] +category = "main" +description = "A data caching implemention based on Redis and redis_structures." +name = "redis-cache" +optional = false +python-versions = "*" +version = "0.1.5" + +[package.dependencies] +python-redis-lock = "*" +redis_structures = "*" +vital-tools = "*" + +[[package]] +category = "main" +description = "Redis data structures wrapped with Python 3." +name = "redis-structures" +optional = false +python-versions = "*" +version = "0.1.7" + +[package.dependencies] +redis = "*" + +[[package]] +category = "main" +description = "Vital tools for writing Python 3.4+ packages." +name = "vital-tools" +optional = false +python-versions = "*" +version = "0.1.13" + +[package.dependencies] +pycrypto = "*" + +[metadata] +content-hash = "8fbb98a0c5cad6ec5b24d4f371c036f84177ba396e9c10eac80bb293e87c53b0" +python-versions = ">=3.6" + +[metadata.files] +pycrypto = [ + {file = "pycrypto-2.6.1.tar.gz", hash = "sha256:f2ce1e989b272cfcb677616763e0a2e7ec659effa67a88aa92b3a65528f60a3c"}, +] +python-redis-lock = [ + {file = "python-redis-lock-3.5.0.tar.gz", hash = "sha256:06f28f63bf4ea3d739ff5c472e76563e24aa5c887002a85cbdb7a5b13aa05897"}, + {file = "python_redis_lock-3.5.0-py2.py3-none-any.whl", hash = "sha256:910ac3c429c2eee4f9f3d6733bc4c722e024e00b887379aefa52ae9376a759b4"}, +] +redis = [ + {file = "redis-3.3.11-py2.py3-none-any.whl", hash = "sha256:3613daad9ce5951e426f460deddd5caf469e08a3af633e9578fc77d362becf62"}, + {file = "redis-3.3.11.tar.gz", hash = "sha256:8d0fc278d3f5e1249967cba2eb4a5632d19e45ce5c09442b8422d15ee2c22cc2"}, +] +redis-cache = [ + {file = "redis-cache-0.1.5.tar.gz", hash = "sha256:cd138557d61f3cc04c3cffabc114b0b1d5fef0349c0838aa19cc984e51c9a5d5"}, +] +redis-structures = [ + {file = "redis_structures-0.1.7.tar.gz", hash = "sha256:0771324fe348583ffdf7025e4034d8da939435e62bac3a1016216fb89b8e25ff"}, +] +vital-tools = [ + {file = "vital-tools-0.1.13.tar.gz", hash = "sha256:72d0fbcc5a16e5c7b1971d7020ed4326144a9a34a37d69bbc2ddc945eaf9cc6d"}, +] diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..7d223d8 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,19 @@ +[tool.poetry] +name = "redis-simple-cache-py3" +version = "0.0.7" +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." +authors = ["Vivek Narayanan, Flávio Juvenal, Sam Zaydel"] +packages = [ + { include = "redis_cache" } +] + +[tool.poetry.dependencies] +python = ">=3.6" +redis_cache = "^0.1.5" +redis = "^3.3.11" + +[tool.poetry.dev-dependencies] + +[build-system] +requires = ["poetry>=0.12"] +build-backend = "poetry.masonry.api" diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 172fe9c..0000000 --- a/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -redis==3.2.0 diff --git a/setup.py b/setup.py deleted file mode 100644 index ac2a2ea..0000000 --- a/setup.py +++ /dev/null @@ -1,26 +0,0 @@ -#coding=utf-8 -import os -from setuptools import setup - -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", - 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", - packages=['redis_cache'], - long_description=openf("README.md").read(), - install_requires=[line.strip() for line in openf("requirements.txt") if line.strip()], - classifiers=[ - "Development Status :: 3 - Alpha", - "Topic :: Utilities", - "License :: OSI Approved :: BSD License", - ], -)