From 075488b6f2b33c211b734dc08414d45cb35c4e68 Mon Sep 17 00:00:00 2001 From: Jesse Myers Date: Wed, 6 May 2015 16:40:46 -0700 Subject: [PATCH 01/30] Bump version to prepare for next release. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index db7d98c..a6218e9 100755 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ from setuptools import setup, find_packages # Match releases to redis-py versions -__version__ = '2.9.0.11' +__version__ = '2.9.0.12' # Jenkins will replace __build__ with a unique value. __build__ = '' From 5e519b9436f7eb879b270693f121adb0c23be16f Mon Sep 17 00:00:00 2001 From: Charles Chan Date: Sat, 23 May 2015 17:48:56 -0700 Subject: [PATCH 02/30] CC - Fix issue #85. Return length of list after LPUSH/RPUSH command. See: http://redis.io/commands/lpush http://redis.io/commands/rpush https://github.com/locationlabs/mockredis/issues/85 --- mockredis/client.py | 9 ++++++++- mockredis/tests/test_list.py | 12 ++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/mockredis/client.py b/mockredis/client.py index 998d3c5..994a31c 100644 --- a/mockredis/client.py +++ b/mockredis/client.py @@ -648,7 +648,11 @@ def lpush(self, key, *args): # Creates the list at this key if it doesn't exist, and appends args to its beginning args_reversed = [self._encode(arg) for arg in args] args_reversed.reverse() - self.redis[self._encode(key)] = args_reversed + redis_list + updated_list = args_reversed + redis_list + self.redis[self._encode(key)] = updated_list + + # Return the length of the list after the push operation + return len(updated_list) def rpop(self, key): """Emulate lpop.""" @@ -673,6 +677,9 @@ def rpush(self, key, *args): # Creates the list at this key if it doesn't exist, and appends args to it redis_list.extend(map(self._encode, args)) + # Return the length of the list after the push operation + return len(redis_list) + def lrem(self, key, value, count=0): """Emulate lrem.""" value = self._encode(value) diff --git a/mockredis/tests/test_list.py b/mockredis/tests/test_list.py index 5269d10..d9b85be 100644 --- a/mockredis/tests/test_list.py +++ b/mockredis/tests/test_list.py @@ -86,15 +86,15 @@ def test_lpush(self): Insertion maintains order but not uniqueness. """ # lpush two values - self.redis.lpush(LIST1, VAL1) - self.redis.lpush(LIST1, VAL2) + eq_(1, self.redis.lpush(LIST1, VAL1)) + eq_(2, self.redis.lpush(LIST1, VAL2)) # validate insertion eq_(b"list", self.redis.type(LIST1)) eq_([bVAL2, bVAL1], self.redis.lrange(LIST1, 0, -1)) # insert two more values with one repeated - self.redis.lpush(LIST1, VAL1, VAL3) + eq_(4, self.redis.lpush(LIST1, VAL1, VAL3)) # validate the update eq_(b"list", self.redis.type(LIST1)) @@ -128,15 +128,15 @@ def test_rpush(self): Insertion maintains order but not uniqueness. """ # rpush two values - self.redis.rpush(LIST1, VAL1) - self.redis.rpush(LIST1, VAL2) + eq_(1, self.redis.rpush(LIST1, VAL1)) + eq_(2, self.redis.rpush(LIST1, VAL2)) # validate insertion eq_(b"list", self.redis.type(LIST1)) eq_([bVAL1, bVAL2], self.redis.lrange(LIST1, 0, -1)) # insert two more values with one repeated - self.redis.rpush(LIST1, VAL1, VAL3) + eq_(4, self.redis.rpush(LIST1, VAL1, VAL3)) # validate the update eq_(b"list", self.redis.type(LIST1)) From e717bb61165954c4c6d254bfc56677253c047f33 Mon Sep 17 00:00:00 2001 From: Tom Linford Date: Mon, 19 Oct 2015 13:25:23 -0700 Subject: [PATCH 03/30] Add transaction method to client --- mockredis/client.py | 26 +++++++++++++++++++++++++- mockredis/tests/test_pipeline.py | 24 ++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/mockredis/client.py b/mockredis/client.py index 998d3c5..2ccd44e 100644 --- a/mockredis/client.py +++ b/mockredis/client.py @@ -11,7 +11,7 @@ from mockredis.clock import SystemClock from mockredis.lock import MockRedisLock -from mockredis.exceptions import RedisError, ResponseError +from mockredis.exceptions import RedisError, ResponseError, WatchError from mockredis.pipeline import MockRedisPipeline from mockredis.script import Script from mockredis.sortedset import SortedSet @@ -75,6 +75,30 @@ def pipeline(self, transaction=True, shard_hint=None): """Emulate a redis-python pipeline.""" return MockRedisPipeline(self, transaction, shard_hint) + def transaction(self, func, *watches, **kwargs): + """ + Convenience method for executing the callable `func` as a transaction + while watching all keys specified in `watches`. The 'func' callable + should expect a single argument which is a Pipeline object. + + Copied directly from redis-py. + """ + shard_hint = kwargs.pop('shard_hint', None) + value_from_callable = kwargs.pop('value_from_callable', False) + watch_delay = kwargs.pop('watch_delay', None) + with self.pipeline(True, shard_hint) as pipe: + while 1: + try: + if watches: + pipe.watch(*watches) + func_value = func(pipe) + exec_value = pipe.execute() + return func_value if value_from_callable else exec_value + except WatchError: + if watch_delay is not None and watch_delay > 0: + time.sleep(watch_delay) + continue + def watch(self, *argv, **kwargs): """ Mock does not support command buffering so watch diff --git a/mockredis/tests/test_pipeline.py b/mockredis/tests/test_pipeline.py index 47eb00d..73e2d51 100644 --- a/mockredis/tests/test_pipeline.py +++ b/mockredis/tests/test_pipeline.py @@ -33,6 +33,30 @@ def test_pipeline_args(self): with self.redis.pipeline(transaction=False, shard_hint=None): pass + def test_transaction(self): + self.redis["a"] = 1 + self.redis["b"] = 2 + has_run = [] + + def my_transaction(pipe): + a_value = pipe.get("a") + assert a_value in (b"1", b"2") + b_value = pipe.get("b") + assert b_value == b"2" + + # silly run-once code... incr's "a" so WatchError should be raised + # forcing this all to run again. this should incr "a" once to "2" + if not has_run: + self.redis.incr("a") + has_run.append(True) + + pipe.multi() + pipe.set("c", int(a_value) + int(b_value)) + + result = self.redis.transaction(my_transaction, "a", "b") + eq_([True], result) + eq_(b"4", self.redis["c"]) + def test_set_and_get(self): """ Pipeline execution returns the pipeline, not the intermediate value. From c8d7c49825e37054345d511ce115d178f9c30e36 Mon Sep 17 00:00:00 2001 From: Kevin Batema Date: Fri, 18 Dec 2015 14:40:19 +0100 Subject: [PATCH 04/30] Added conversion from glob stype pattern to regex for keys fuction --- mockredis/client.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/mockredis/client.py b/mockredis/client.py index 998d3c5..6648d7b 100644 --- a/mockredis/client.py +++ b/mockredis/client.py @@ -8,6 +8,7 @@ import re import sys import time +import fnmatch from mockredis.clock import SystemClock from mockredis.lock import MockRedisLock @@ -123,10 +124,14 @@ def type(self, key): def keys(self, pattern='*'): """Emulate keys.""" # Make a regex out of pattern. The only special matching character we look for is '*' - regex = re.compile(b'^' + re.escape(self._encode(pattern)).replace(b'\\*', b'.*') + b'$') + regex = fnmatch.translate(pattern) # re.compile(b'^' + re.escape(self._encode(pattern)).replace(b'\\*', b'.*') + b'$') + regex = re.compile(re.sub(r'(^|[^\\])\.', r'\1[^/]', regex)) + result = [] # Find every key that matches the pattern - result = [key for key in self.redis.keys() if regex.match(key)] + for key in self.redis.keys(): + if regex.match(key.decode()): + result.append(key) return result From 06f3760cfd0374d2247f60c772d64da41b2173be Mon Sep 17 00:00:00 2001 From: Kevin Batema Date: Fri, 18 Dec 2015 14:47:16 +0100 Subject: [PATCH 05/30] Cleanup --- mockredis/client.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/mockredis/client.py b/mockredis/client.py index 6648d7b..2b8c334 100644 --- a/mockredis/client.py +++ b/mockredis/client.py @@ -123,17 +123,12 @@ def type(self, key): def keys(self, pattern='*'): """Emulate keys.""" - # Make a regex out of pattern. The only special matching character we look for is '*' - regex = fnmatch.translate(pattern) # re.compile(b'^' + re.escape(self._encode(pattern)).replace(b'\\*', b'.*') + b'$') + # Make a regex out of glob styled pattern. + regex = fnmatch.translate(pattern) regex = re.compile(re.sub(r'(^|[^\\])\.', r'\1[^/]', regex)) - result = [] # Find every key that matches the pattern - for key in self.redis.keys(): - if regex.match(key.decode()): - result.append(key) - - return result + return [key for key in self.redis.keys() if regex.match(key.decode())] def delete(self, *keys): """Emulate delete.""" From 8f3df2a9ba7c3985883099c0ff591f3f432d631b Mon Sep 17 00:00:00 2001 From: Kevin Batema Date: Sat, 19 Dec 2015 11:20:39 +0100 Subject: [PATCH 06/30] Updated the tests to reflect the changes --- mockredis/client.py | 9 +++++++-- mockredis/tests/test_redis.py | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/mockredis/client.py b/mockredis/client.py index 2b8c334..2a2353b 100644 --- a/mockredis/client.py +++ b/mockredis/client.py @@ -123,12 +123,17 @@ def type(self, key): def keys(self, pattern='*'): """Emulate keys.""" - # Make a regex out of glob styled pattern. + # making sure the pattern is in unicode + if type(pattern) is not unicode: + pattern = pattern.decode('utf-8') + + # Make regex out of glob styled pattern. + print(type(pattern)) regex = fnmatch.translate(pattern) regex = re.compile(re.sub(r'(^|[^\\])\.', r'\1[^/]', regex)) # Find every key that matches the pattern - return [key for key in self.redis.keys() if regex.match(key.decode())] + return [key for key in self.redis.keys() if regex.match(key.decode('utf-8'))] def delete(self, *keys): """Emulate delete.""" diff --git a/mockredis/tests/test_redis.py b/mockredis/tests/test_redis.py index f502db7..13472b8 100644 --- a/mockredis/tests/test_redis.py +++ b/mockredis/tests/test_redis.py @@ -199,6 +199,7 @@ def test_keys_unicode(self): self.redis.set(key, "bar") eq_([key_as_utf8], self.redis.keys("*")) eq_([key_as_utf8], self.redis.keys("eat*")) + eq_([key_as_utf8], self.redis.keys("[ea]at * n?[a-z]")) unicode_prefix = b'eat \xf0\x9f\x8d\xb0*'.decode('utf-8') eq_([key_as_utf8], self.redis.keys(unicode_prefix)) From 37510715dcb03e6ba76e2eae3444272e61499086 Mon Sep 17 00:00:00 2001 From: Kevin Batema Date: Sat, 19 Dec 2015 11:37:19 +0100 Subject: [PATCH 07/30] Fixed python 3 compatiblity --- mockredis/client.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/mockredis/client.py b/mockredis/client.py index 2a2353b..ba0cace 100644 --- a/mockredis/client.py +++ b/mockredis/client.py @@ -123,12 +123,15 @@ def type(self, key): def keys(self, pattern='*'): """Emulate keys.""" - # making sure the pattern is in unicode - if type(pattern) is not unicode: + # making sure the pattern is unicode/str. + try: pattern = pattern.decode('utf-8') + # This throws an AttributeError in python 3, or an + # UnicodeEncodeError in python 2 + except (AttributeError, UnicodeEncodeError): + pass # Make regex out of glob styled pattern. - print(type(pattern)) regex = fnmatch.translate(pattern) regex = re.compile(re.sub(r'(^|[^\\])\.', r'\1[^/]', regex)) From 006ddf95459358fa9229d57656c0c64bc7b989e2 Mon Sep 17 00:00:00 2001 From: Vladimir Bolshakov Date: Mon, 1 Feb 2016 18:42:54 +0300 Subject: [PATCH 08/30] Deepcopy timeouts in do_expire method to avoid RuntimeError in Python 3. --- mockredis/client.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mockredis/client.py b/mockredis/client.py index 998d3c5..518ef8e 100644 --- a/mockredis/client.py +++ b/mockredis/client.py @@ -1,5 +1,6 @@ from __future__ import division from collections import defaultdict +from copy import deepcopy from itertools import chain from datetime import datetime, timedelta from hashlib import sha1 @@ -221,7 +222,9 @@ def do_expire(self): """ Expire objects assuming now == time """ - for key, value in self.timeouts.items(): + # Deep copy to avoid RuntimeError: dictionary changed size during iteration + _timeouts = deepcopy(self.timeouts) + for key, value in _timeouts.items(): if value - self.clock.now() < timedelta(0): del self.timeouts[key] # removing the expired key From e4feb6e919f8569eab58422a0528160b7940abf0 Mon Sep 17 00:00:00 2001 From: Jeremiah Porten Date: Tue, 1 Mar 2016 22:21:48 -0800 Subject: [PATCH 09/30] Adds dbsize() function. Closes issue #100 --- mockredis/client.py | 3 +++ mockredis/tests/test_redis.py | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/mockredis/client.py b/mockredis/client.py index ba0cace..d5d2bac 100644 --- a/mockredis/client.py +++ b/mockredis/client.py @@ -255,6 +255,9 @@ def _rename(self, old_key, new_key, nx=False): return True return False + def dbsize(self): + return len(self.redis.keys()) + # String Functions # def get(self, key): diff --git a/mockredis/tests/test_redis.py b/mockredis/tests/test_redis.py index 13472b8..2dd1b8a 100644 --- a/mockredis/tests/test_redis.py +++ b/mockredis/tests/test_redis.py @@ -246,3 +246,9 @@ def test_renamenx(self): eq_(b"bar2", self.redis.get("foo2")) eq_(self.redis.renamenx("foo", "foo3"), 1) eq_(b"bar", self.redis.get("foo3")) + + def test_dbsize(self): + self.redis["foo"] = "bar" + eq_(1, self.redis.dbsize()) + del self.redis["foo"] + eq_(0, self.redis.dbsize()) From f871d02d298114e08d964903be66004fd7c3f341 Mon Sep 17 00:00:00 2001 From: Jeremiah Porten Date: Wed, 2 Mar 2016 16:11:09 -0800 Subject: [PATCH 10/30] Updates to change log --- CHANGES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 20de6a0..1a2d0fd 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,6 @@ +Version 2.9.0.12 + - Support: `dbsize` + Version 2.9.0.11 - Support: `scan_iter`, `sscan_iter`, `zscan_iter`, `hscan_iter` From 5f106f2e6b03c1919bb08c766bae08bfdc6110eb Mon Sep 17 00:00:00 2001 From: Jeremiah Porten Date: Wed, 2 Mar 2016 16:14:52 -0800 Subject: [PATCH 11/30] Bumping version after release --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index a6218e9..c217848 100755 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ from setuptools import setup, find_packages # Match releases to redis-py versions -__version__ = '2.9.0.12' +__version__ = '2.9.0.13' # Jenkins will replace __build__ with a unique value. __build__ = '' From 0d2106897b64fab405393fa160b5f33215f7d582 Mon Sep 17 00:00:00 2001 From: David Baumgold Date: Tue, 12 Apr 2016 17:55:19 -0400 Subject: [PATCH 12/30] Add support for `from_url` classmethod --- mockredis/client.py | 8 ++++++++ mockredis/tests/test_factories.py | 14 ++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/mockredis/client.py b/mockredis/client.py index d5d2bac..00a47a6 100644 --- a/mockredis/client.py +++ b/mockredis/client.py @@ -58,6 +58,10 @@ def __init__(self, # Dictionary from script to sha ''Script'' self.shas = dict() + @classmethod + def from_url(http://github.com/cls,%20url,%20db=None,%20**kwargs): + return cls(**kwargs) + # Connection Functions # def echo(self, msg): @@ -1509,6 +1513,8 @@ def mock_redis_client(**kwargs): """ return MockRedis() +mock_redis_client.from_url = mock_redis_client + def mock_strict_redis_client(**kwargs): """ @@ -1517,3 +1523,5 @@ def mock_strict_redis_client(**kwargs): instead of a StrictRedis object. """ return MockRedis(strict=True) + +mock_strict_redis_client.from_url = mock_strict_redis_client diff --git a/mockredis/tests/test_factories.py b/mockredis/tests/test_factories.py index 103b3f5..0d2084d 100644 --- a/mockredis/tests/test_factories.py +++ b/mockredis/tests/test_factories.py @@ -13,8 +13,22 @@ def test_mock_redis_client(): ok_(not mock_redis_client(host="localhost", port=6379).strict) +def test_mock_redis_client_from_url(): + """ + Test that we can pass kwargs to the Redis from_url mock/patch target. + """ + ok_(not mock_redis_client.from_url(http://github.com/host=%22localhost%22,%20port=6379).strict) + + def test_mock_strict_redis_client(): """ Test that we can pass kwargs to the StrictRedis mock/patch target. """ ok_(mock_strict_redis_client(host="localhost", port=6379).strict) + + +def test_mock_strict_redis_client_from_url(): + """ + Test that we can pass kwargs to the StrictRedis from_url mock/patch target. + """ + ok_(mock_strict_redis_client.from_url(http://github.com/host=%22localhost%22,%20port=6379).strict) From 4062e1d772157d5fc61c4a43a13c2ab836a91d40 Mon Sep 17 00:00:00 2001 From: Srikalyan Swayampakula Date: Mon, 18 Apr 2016 11:07:38 -0700 Subject: [PATCH 13/30] Updated changes for the release. --- CHANGES.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 1a2d0fd..6ad9790 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,8 @@ +Version 2.9.1 + - Support for `from_url` + - Support for `transaction` + - Fix `do_expire` method in Python 3 + Version 2.9.0.12 - Support: `dbsize` From fc2d5aecb063ce2bc0b9ec69b907aa99c0bf0f26 Mon Sep 17 00:00:00 2001 From: Srikalyan Swayampakula Date: Mon, 18 Apr 2016 11:07:38 -0700 Subject: [PATCH 14/30] Updated changes for the release. --- CHANGES.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 1a2d0fd..6ad9790 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,8 @@ +Version 2.9.1 + - Support for `from_url` + - Support for `transaction` + - Fix `do_expire` method in Python 3 + Version 2.9.0.12 - Support: `dbsize` From 1c7d780d30087da3f2db7291ddf59b844c4593a5 Mon Sep 17 00:00:00 2001 From: Srikalyan Swayampakula Date: Mon, 18 Apr 2016 11:18:53 -0700 Subject: [PATCH 15/30] Fixed the version number. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index a6218e9..a0e4481 100755 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ from setuptools import setup, find_packages # Match releases to redis-py versions -__version__ = '2.9.0.12' +__version__ = '2.9.1' # Jenkins will replace __build__ with a unique value. __build__ = '' From 83b4f5e8c77b9149a99e02fe514dcc454508bbf5 Mon Sep 17 00:00:00 2001 From: Srikalyan Swayampakula Date: Mon, 18 Apr 2016 11:21:16 -0700 Subject: [PATCH 16/30] Fixed the versioning issue and releasing 2.9.2. --- CHANGES.md | 3 +++ setup.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 6ad9790..6c96f0a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,6 @@ +Version 2.9.2 + - Fixed the versioning issue. + Version 2.9.1 - Support for `from_url` - Support for `transaction` diff --git a/setup.py b/setup.py index a0e4481..6de8cae 100755 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ from setuptools import setup, find_packages # Match releases to redis-py versions -__version__ = '2.9.1' +__version__ = '2.9.2' # Jenkins will replace __build__ with a unique value. __build__ = '' From f0d8891c65327e3174538d15af9f5818b3e58611 Mon Sep 17 00:00:00 2001 From: Srikalyan Swayampakula Date: Mon, 18 Apr 2016 12:05:17 -0700 Subject: [PATCH 17/30] Releasing 2.9.3 so bumping the version to 2.9.4. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index aa59785..5724015 100755 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ from setuptools import setup, find_packages # Match releases to redis-py versions -__version__ = '2.9.3' +__version__ = '2.9.4' # Jenkins will replace __build__ with a unique value. __build__ = '' From caae3a2c34209ee791f672c4230d9c44fc95888f Mon Sep 17 00:00:00 2001 From: Srikalyan Swayampakula Date: Mon, 18 Apr 2016 14:32:03 -0700 Subject: [PATCH 18/30] Trying the new password for ll account. --- .travis.yml | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index cb06a0c..9646310 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ deploy: provider: pypi user: github-ll password: - secure: Ol3Gxz2iQEh7Oz64FZJfwLJK/r8QLlnE3aFKv6TkTxn8DedXK+mLUTC0PwueBSOIRGpnxlHwQyzrzxZWs2QOUoyB+Nbx6L1wU+NsgviNKJjAln4/tV4dAeI7GRJD2cDkRH9w2QihWnRFRh7BbmhfsD4WrsELP5k6onbVrQwU/Ao= + secure: a64VGzyBWpg9qNv6NnURDwuDxDKYeIvWnfjTctM+BgNurPfbJ9ohYiCbJIEGR9KnA4el3RPNe8AiaOJhiP7xo2x4fqvT2HRWHnarl6jpgz0Fe+0LOcop8sknxz5ePDSFZSaQYpIWJTGkDaBBHMtt7CMNr3UbV7G/HT8hyl5r69Y= on: tags: true repo: locationlabs/mockredis diff --git a/setup.py b/setup.py index 5724015..aa59785 100755 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ from setuptools import setup, find_packages # Match releases to redis-py versions -__version__ = '2.9.4' +__version__ = '2.9.3' # Jenkins will replace __build__ with a unique value. __build__ = '' From 9a8c70c423a26dc76d71e735471847002f8b2ed5 Mon Sep 17 00:00:00 2001 From: Srikalyan Swayampakula Date: Mon, 18 Apr 2016 14:51:13 -0700 Subject: [PATCH 19/30] Figured out the exact issue with travis password. Hopefull this would fix it. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9646310..3d203af 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ deploy: provider: pypi user: github-ll password: - secure: a64VGzyBWpg9qNv6NnURDwuDxDKYeIvWnfjTctM+BgNurPfbJ9ohYiCbJIEGR9KnA4el3RPNe8AiaOJhiP7xo2x4fqvT2HRWHnarl6jpgz0Fe+0LOcop8sknxz5ePDSFZSaQYpIWJTGkDaBBHMtt7CMNr3UbV7G/HT8hyl5r69Y= + secure: DPz0VuHjZp/586ImakwtjqQzEIq6crQLMv1/Z4OKD1C1XY/KQ7uEgYTGSEDR4e2m5K8id3ZXkAEQSuopyrQ0on6KuwTmfT9U7dsk3ijCkHc2XSwfC5uU7eWgrbn62wVWo3kchBerAWOvOmXiXBdTiIOIfJ7MvvxcfAkz/1zRYx8= on: tags: true repo: locationlabs/mockredis From 9772a4a07e9332136ed069417c0ef98d74cc0b35 Mon Sep 17 00:00:00 2001 From: Srikalyan Swayampakula Date: Mon, 18 Apr 2016 15:21:44 -0700 Subject: [PATCH 20/30] Trying one last time encrypt passwords is crazy hard. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3d203af..67b36bb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ deploy: provider: pypi user: github-ll password: - secure: DPz0VuHjZp/586ImakwtjqQzEIq6crQLMv1/Z4OKD1C1XY/KQ7uEgYTGSEDR4e2m5K8id3ZXkAEQSuopyrQ0on6KuwTmfT9U7dsk3ijCkHc2XSwfC5uU7eWgrbn62wVWo3kchBerAWOvOmXiXBdTiIOIfJ7MvvxcfAkz/1zRYx8= + secure: Pda4pJH7Jyyfk1XXRFh4PahRksUpWpKhLtTRU28mhhYi5ubhzrW+KzHTbPcopdmnvb0ZEX5aAs0bS1JkAL9+U5m6zlKMUp89L8I0iIxsxcVa4kOzp34FbL4rwcYUj9hTSXhHMPSrKc8/8Z+FWPFhZFTk+NwKq33AnB/lWISY1wE= on: tags: true repo: locationlabs/mockredis From 5a2559bee81eb218c2b4f4fb159eb637904dff0c Mon Sep 17 00:00:00 2001 From: Srikalyan Swayampakula Date: Mon, 18 Apr 2016 16:06:38 -0700 Subject: [PATCH 21/30] Trying from bash instead of zsh for password. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 67b36bb..4a1856e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ deploy: provider: pypi user: github-ll password: - secure: Pda4pJH7Jyyfk1XXRFh4PahRksUpWpKhLtTRU28mhhYi5ubhzrW+KzHTbPcopdmnvb0ZEX5aAs0bS1JkAL9+U5m6zlKMUp89L8I0iIxsxcVa4kOzp34FbL4rwcYUj9hTSXhHMPSrKc8/8Z+FWPFhZFTk+NwKq33AnB/lWISY1wE= + secure: Zrl29yzW99UP03FQQnMhu/aANUMmkpgp20GaVwKmv8yemqj1D2he80h6QlBMXiGpTgk/egXldkPhFkOPjc08bPstcm71PmY8+sMmZ92netblx9hyUG0uMUJo7ctLnCPYgm2v+EdfCKXs+eK7roMM8leXBXAQMwzVHZQRk1w8D7s= on: tags: true repo: locationlabs/mockredis From 517897e46d12d8b64c2f8b55cfa1a895519f3821 Mon Sep 17 00:00:00 2001 From: Srikalyan Swayampakula Date: Mon, 18 Apr 2016 16:21:42 -0700 Subject: [PATCH 22/30] Trying a new password. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4a1856e..77bce44 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ deploy: provider: pypi user: github-ll password: - secure: Zrl29yzW99UP03FQQnMhu/aANUMmkpgp20GaVwKmv8yemqj1D2he80h6QlBMXiGpTgk/egXldkPhFkOPjc08bPstcm71PmY8+sMmZ92netblx9hyUG0uMUJo7ctLnCPYgm2v+EdfCKXs+eK7roMM8leXBXAQMwzVHZQRk1w8D7s= + secure: WZNNslmr6ELiasA6IhO9QDQ/g7758WjezVLqC3Ebo3EgAsUOFeCvtqODf3U8czz4UxORrVL7xWN/lUEOCG/ImDoXa9W27h8kl3D0pP9s8FDNngZspB5c3xhZhQesiqB6n8Fyi2dLic9QYUUIgquo2w+w/r5rRHvplI9OVbIGuVM= on: tags: true repo: locationlabs/mockredis From 5e4fb95dee0e9d7c6bbb77ab0458649efdfd1ac3 Mon Sep 17 00:00:00 2001 From: Yossi Gottlieb Date: Tue, 19 May 2015 10:21:18 +0300 Subject: [PATCH 23/30] Add basic config_set / config_get support. --- mockredis/client.py | 22 ++++++++++++++++++++++ mockredis/tests/test_config.py | 20 ++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 mockredis/tests/test_config.py diff --git a/mockredis/client.py b/mockredis/client.py index ab2a010..05c2439 100644 --- a/mockredis/client.py +++ b/mockredis/client.py @@ -53,6 +53,7 @@ def __init__(self, self.blocking_sleep_interval = blocking_sleep_interval # The 'Redis' store self.redis = defaultdict(dict) + self.redis_config = defaultdict(dict) self.timeouts = defaultdict(dict) # The 'PubSub' store self.pubsub = defaultdict(list) @@ -1396,6 +1397,27 @@ def _normalize_command_response(self, command, response): return response + # Config Set/Get commands # + + def config_set(self, name, value): + """ + Set a configuration parameter. + """ + self.redis_config[name] = value + + def config_get(self, pattern='*'): + """ + Get one or more configuration parameters. + """ + result = {} + for name, value in self.redis_config.items(): + if fnmatch.fnmatch(name, pattern): + try: + result[name] = int(value) + except ValueError: + result[name] = value + return result + # PubSub commands # def publish(self, channel, message): diff --git a/mockredis/tests/test_config.py b/mockredis/tests/test_config.py new file mode 100644 index 0000000..24a7f94 --- /dev/null +++ b/mockredis/tests/test_config.py @@ -0,0 +1,20 @@ +from nose.tools import eq_, ok_ + +from mockredis.tests.fixtures import setup, teardown + + +class TestRedisConfig(object): + """Redis config set/get tests""" + + def setup(self): + setup(self) + + def teardown(self): + teardown(self) + + def test_config_set(self): + eq_(self.redis.config_get('config-param'), {}) + self.redis.config_set('config-param', 'value') + eq_(self.redis.config_get('config-param'), {'config-param': 'value'}) + eq_(self.redis.config_get('config*'), {'config-param': 'value'}) + From f6f25da72d0c869c5658fbad969aafd687d70a93 Mon Sep 17 00:00:00 2001 From: Amotz Getzov Date: Sun, 26 Jun 2016 12:05:39 +0300 Subject: [PATCH 24/30] Update contribution guids to GitHub Flow. --- CONTRIBUTING.md | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3ad86b2..a412854 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,28 +1,16 @@ # Contributing -Mock Redis uses [git-flow][1] for its branch management. +Mock Redis uses GitHub Flow for its branch management. We ask that contributors to this project please: - 1. Implement changes in new git branches, following git-flow's model: + 1. Folow [GitHub Flow][1]. - - Changes based off of *develop* will receive the least amount of skepticism. - - - Changes based off of a *release* branches (if one exists) will be considered, - especially for small bug fixes relevant to the release. We are not likely to - accept new features against *release* branches. - - - Changes based off of *master* or a prior release tag will be given the most - skepticism. We may accept patches for major bugs against past releases, but - would prefer to see such changes follow the normal git-flow process. - - We will not accept new features based off of *master*. - 2. Limit the scope of changes to a single bug fix or feature per branch. 3. Treat documentation and unit tests as an essential part of any change. - 4. Update the change log appropriately. + 4. Folow existing style, contributions should look as part of the project. Thank you! - [1]: https://github.com/nvie/gitflow + [1]: https://guides.github.com/introduction/flow/ From aca998fc31192d4267907ce783af99dcc9bf35e8 Mon Sep 17 00:00:00 2001 From: Amotz Getzov Date: Sun, 4 Dec 2016 15:26:19 +0200 Subject: [PATCH 25/30] Removed travis use of no longer supported pip switch --use-mirrors . --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 77bce44..e21cb75 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ python: - '3.4' - pypy - pypy3 -install: pip install . --use-mirrors +install: pip install . script: python setup.py nosetests deploy: provider: pypi From d8e0c0adb51017059e9b1828f857c10ad1262127 Mon Sep 17 00:00:00 2001 From: John Ubante Date: Wed, 26 Apr 2017 11:49:46 -0700 Subject: [PATCH 26/30] fix yo typo BLAMMO --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a412854..3c63fb5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,7 +9,7 @@ We ask that contributors to this project please: 3. Treat documentation and unit tests as an essential part of any change. - 4. Folow existing style, contributions should look as part of the project. + 4. Follow existing style, contributions should look as part of the project. Thank you! From 994865cb44598c4a5ca4951ddf64c8fb76148aed Mon Sep 17 00:00:00 2001 From: William Richard Date: Wed, 25 Apr 2018 11:09:19 -0400 Subject: [PATCH 27/30] Make the argument name matche redis-py This should fix https://github.com/locationlabs/mockredis/issues/78 --- mockredis/client.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mockredis/client.py b/mockredis/client.py index 926e048..6278f40 100644 --- a/mockredis/client.py +++ b/mockredis/client.py @@ -380,16 +380,16 @@ def _should_set(self, key, mode): # for all other cases, return true return True - def setex(self, key, time, value): + def setex(self, name, time, value): """ - Set the value of ``key`` to ``value`` that expires in ``time`` + Set the value of ``name`` to ``value`` that expires in ``time`` seconds. ``time`` can be represented by an integer or a Python timedelta object. """ if not self.strict: # when not strict mode swap value and time args order time, value = value, time - return self.set(key, value, ex=time) + return self.set(name, value, ex=time) def psetex(self, key, time, value): """ From 99fc1af668a0872262a00752800bdacb168dd0ee Mon Sep 17 00:00:00 2001 From: Yury Paykov Date: Fri, 29 Jun 2018 22:44:17 +0500 Subject: [PATCH 28/30] Mset should fail on empty kwargs/args (#146) * Replicates redis library error 'wrong number of arguments for 'mset' command' --- mockredis/client.py | 9 ++++++--- mockredis/tests/test_string.py | 22 ++++++++++++++++++++-- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/mockredis/client.py b/mockredis/client.py index 6278f40..e67edbc 100644 --- a/mockredis/client.py +++ b/mockredis/client.py @@ -408,12 +408,15 @@ def mset(self, *args, **kwargs): Sets key/values based on a mapping. Mapping can be supplied as a single dictionary argument or as kwargs. """ + mapping = kwargs if args: if len(args) != 1 or not isinstance(args[0], dict): raise RedisError('MSET requires **kwargs or a single dict arg') - mapping = args[0] - else: - mapping = kwargs + mapping.update(args[0]) + + if len(mapping) == 0: + raise ResponseError("wrong number of arguments for 'mset' command") + for key, value in mapping.items(): self.set(key, value) return True diff --git a/mockredis/tests/test_string.py b/mockredis/tests/test_string.py index 4934921..3642123 100644 --- a/mockredis/tests/test_string.py +++ b/mockredis/tests/test_string.py @@ -3,7 +3,11 @@ from nose.tools import eq_, ok_ from mockredis.client import get_total_milliseconds -from mockredis.tests.fixtures import raises_response_error, setup, teardown +from mockredis.tests.fixtures import ( + raises_response_error, + setup, + teardown, +) class TestRedisString(object): @@ -203,7 +207,21 @@ def test_strict_setex_zero_expiration(self): def test_mset(self): ok_(self.redis.mset({"key1": "hello", "key2": ""})) ok_(self.redis.mset(**{"key3": "world", "key2": "there"})) - eq_([b"hello", b"there", b"world"], self.redis.mget("key1", "key2", "key3")) + ok_(self.redis.mset( + {"key4": "ican"}, **{"key4": "haz", "key5": "cheezburger"}) + ) + eq_( + [b"hello", b"there", b"world", b"ican", b"cheezburger"], + self.redis.mget("key1", "key2", "key3", "key4", "key5") + ) + + @raises_response_error + def test_mset_empty_kwargs(self): + self.redis.mset(**{}) + + @raises_response_error + def test_mset_empty_args(self): + self.redis.mset({}) def test_msetnx(self): ok_(self.redis.msetnx({"key1": "hello", "key2": "there"})) From fd4e3117066ff0c24e86ebca007853a8092e3254 Mon Sep 17 00:00:00 2001 From: Dave King Date: Wed, 5 Sep 2018 11:00:28 -0700 Subject: [PATCH 29/30] Fail msetnx if passed arguments are empty (#152) Resolves #151 --- mockredis/client.py | 3 +++ mockredis/tests/test_string.py | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/mockredis/client.py b/mockredis/client.py index e67edbc..5de0b2a 100644 --- a/mockredis/client.py +++ b/mockredis/client.py @@ -434,6 +434,9 @@ def msetnx(self, *args, **kwargs): else: mapping = kwargs + if len(mapping) == 0: + raise ResponseError("wrong number of arguments for 'msetnx' command") + for key in mapping.keys(): if self._encode(key) in self.redis: return False diff --git a/mockredis/tests/test_string.py b/mockredis/tests/test_string.py index 3642123..eaa99ca 100644 --- a/mockredis/tests/test_string.py +++ b/mockredis/tests/test_string.py @@ -228,6 +228,10 @@ def test_msetnx(self): ok_(not self.redis.msetnx(**{"key3": "world", "key2": "there"})) eq_([b"hello", b"there", None], self.redis.mget("key1", "key2", "key3")) + @raises_response_error + def test_msetnx_empty_args(self): + self.redis.msetnx({}) + def test_psetex(self): test_cases = [200, timedelta(milliseconds=250)] for case in test_cases: From 1a8d82f44d217fc9c64143940a59f2f6af403fb8 Mon Sep 17 00:00:00 2001 From: safd22 <50186776+safd22@users.noreply.github.com> Date: Wed, 1 May 2019 16:46:09 -0700 Subject: [PATCH 30/30] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index a4a5a41..2b4f653 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +THIS REPO IS NO LONGER SUPPORTED. IF YOU ARE LOOKING FOR A SIMILAR SOLUTION, WE WOULD RECOMMEND LOOKING AT https://github.com/jamesls/fakeredis + # Mock for the redis-py client library Supports writing tests for code using the [redis-py][redis-py] library