Hello community, here is the log from the commit of package python-fakeredis for openSUSE:Factory checked in at 2019-09-13 15:03:02 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-fakeredis (Old) and /work/SRC/openSUSE:Factory/.python-fakeredis.new.7948 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-fakeredis" Fri Sep 13 15:03:02 2019 rev:3 rq:730624 version:1.0.5 Changes: -------- --- /work/SRC/openSUSE:Factory/python-fakeredis/python-fakeredis.changes 2019-08-22 10:55:56.973671082 +0200 +++ /work/SRC/openSUSE:Factory/.python-fakeredis.new.7948/python-fakeredis.changes 2019-09-13 15:04:40.153265016 +0200 @@ -1,0 +2,6 @@ +Fri Sep 13 07:55:04 UTC 2019 - Tomáš Chvátal <tchva...@suse.com> + +- Update to 1.0.5: + * No upstream changelog + +------------------------------------------------------------------- Old: ---- fakeredis-1.0.4.tar.gz New: ---- fakeredis-1.0.5.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-fakeredis.spec ++++++ --- /var/tmp/diff_new_pack.LdFRRQ/_old 2019-09-13 15:04:40.649264911 +0200 +++ /var/tmp/diff_new_pack.LdFRRQ/_new 2019-09-13 15:04:40.649264911 +0200 @@ -18,7 +18,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-fakeredis -Version: 1.0.4 +Version: 1.0.5 Release: 0 Summary: Fake implementation of redis API for testing purposes License: BSD-3-Clause AND MIT @@ -37,7 +37,6 @@ Suggests: python-lupa BuildArch: noarch # SECTION test requirements -# bug in https://github.com/jamesls/fakeredis/issues/235 BuildRequires: %{python_module future} BuildRequires: %{python_module lupa} BuildRequires: %{python_module redis} ++++++ fakeredis-1.0.4.tar.gz -> fakeredis-1.0.5.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fakeredis-1.0.4/PKG-INFO new/fakeredis-1.0.5/PKG-INFO --- old/fakeredis-1.0.4/PKG-INFO 2019-08-14 11:55:44.000000000 +0200 +++ new/fakeredis-1.0.5/PKG-INFO 2019-09-05 11:51:08.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: fakeredis -Version: 1.0.4 +Version: 1.0.5 Summary: Fake implementation of redis API for testing purposes. Home-page: https://github.com/jamesls/fakeredis Author: James Saryerwinnie @@ -233,7 +233,6 @@ * object * restore * touch - * unlink * wait @@ -381,6 +380,12 @@ Revision history ================ + 1.0.5 + ----- + - `#247 <https://github.com/jamesls/fakeredis/pull/247>`_ Support NX/XX/CH flags in ZADD command + - `#250 <https://github.com/jamesls/fakeredis/pull/250>`_ Implement UNLINK command + - `#252 <https://github.com/jamesls/fakeredis/pull/252>`_ Fix implementation of ZSCAN + 1.0.4 ----- - `#240 <https://github.com/jamesls/fakeredis/issues/240>`_ `#242 <https://github.com/jamesls/fakeredis/issues/242>`_ Support for ``redis==3.3`` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fakeredis-1.0.4/README.rst new/fakeredis-1.0.5/README.rst --- old/fakeredis-1.0.4/README.rst 2019-08-14 11:31:28.000000000 +0200 +++ new/fakeredis-1.0.5/README.rst 2019-09-05 11:38:09.000000000 +0200 @@ -223,7 +223,6 @@ * object * restore * touch - * unlink * wait @@ -371,6 +370,12 @@ Revision history ================ +1.0.5 +----- +- `#247 <https://github.com/jamesls/fakeredis/pull/247>`_ Support NX/XX/CH flags in ZADD command +- `#250 <https://github.com/jamesls/fakeredis/pull/250>`_ Implement UNLINK command +- `#252 <https://github.com/jamesls/fakeredis/pull/252>`_ Fix implementation of ZSCAN + 1.0.4 ----- - `#240 <https://github.com/jamesls/fakeredis/issues/240>`_ `#242 <https://github.com/jamesls/fakeredis/issues/242>`_ Support for ``redis==3.3`` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fakeredis-1.0.4/fakeredis/__init__.py new/fakeredis-1.0.5/fakeredis/__init__.py --- old/fakeredis-1.0.4/fakeredis/__init__.py 2019-08-14 11:30:05.000000000 +0200 +++ new/fakeredis-1.0.5/fakeredis/__init__.py 2019-09-05 11:38:17.000000000 +0200 @@ -1,4 +1,4 @@ from ._server import FakeServer, FakeRedis, FakeStrictRedis, FakeConnection # noqa: F401 -__version__ = '1.0.4' +__version__ = '1.0.5' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fakeredis-1.0.4/fakeredis/_server.py new/fakeredis-1.0.5/fakeredis/_server.py --- old/fakeredis-1.0.4/fakeredis/_server.py 2019-08-14 11:07:24.000000000 +0200 +++ new/fakeredis-1.0.5/fakeredis/_server.py 2019-09-05 11:34:50.000000000 +0200 @@ -47,6 +47,7 @@ SRC_DST_SAME_MSG = "source and destination objects are the same" NO_KEY_MSG = "no such key" INDEX_ERROR_MSG = "index out of range" +ZADD_NX_XX_ERROR_MSG = "ZADD allows either 'nx' or 'xx', not both" ZUNIONSTORE_KEYS_MSG = "at least 1 input key is needed for ZUNIONSTORE/ZINTERSTORE" WRONG_ARGS_MSG = "wrong number of arguments for '{}' command" UNKNOWN_COMMAND_MSG = "unknown command '{}'" @@ -869,7 +870,8 @@ if pattern is not None: regex = compile_pattern(pattern) for val in itertools.islice(data, cursor, result_cursor): - if regex.match(val): + compare_val = val[0] if isinstance(val, tuple) else val + if regex.match(compare_val): result_data.append(val) else: result_data = data[cursor:result_cursor] @@ -911,8 +913,7 @@ # Key commands # TODO: lots - @command((Key(),), (Key(),), name='del') - def del_(self, *keys): + def _delete(self, *keys): ans = 0 done = set() for key in keys: @@ -922,6 +923,14 @@ ans += 1 return ans + @command((Key(),), (Key(),), name='del') + def del_(self, *keys): + return self._delete(*keys) + + @command((Key(),), (Key(),), name='unlink') + def unlink(self, *keys): + return self._delete(*keys) + @command((Key(),), (Key(),)) def exists(self, *keys): ret = 0 @@ -1895,19 +1904,55 @@ @command((Key(ZSet), bytes, bytes), (bytes,)) def zadd(self, key, *args): - # TODO: handle NX, XX, CH, INCR + # TODO: handle INCR zset = key.value - if len(args) % 2 != 0: + + i = 0 + ch = False + nx = False + xx = False + while i < len(args): + if casematch(args[i], b'ch'): + ch = True + i += 1 + elif casematch(args[i], b'nx'): + nx = True + i += 1 + elif casematch(args[i], b'xx'): + xx = True + i += 1 + else: + # First argument not matching flags indicates the start of + # score pairs. + break + + if nx and xx: + raise redis.ResponseError(ZADD_NX_XX_ERROR_MSG) + + elements = args[i:] + if not elements or len(elements) % 2 != 0: raise redis.ResponseError(SYNTAX_ERROR_MSG) - items = [] # Parse all scores first, before updating - for i in range(0, len(args), 2): - score = Float.decode(args[i]) - items.append((score, args[i + 1])) + items = [ + (Float.decode(elements[j]), elements[j + 1]) + for j in range(0, len(elements), 2) + ] old_len = len(zset) - for item in items: - if zset.add(item[1], item[0]): - key.updated() + changed_items = 0 + + for item_score, item_name in items: + if ( + (not nx or item_name not in zset) + and (not xx or item_name in zset) + ): + if zset.add(item_name, item_score): + changed_items += 1 + + if changed_items: + key.updated() + + if ch: + return changed_items return len(zset) - old_len @command((Key(ZSet),)) @@ -2053,7 +2098,12 @@ @command((Key(ZSet), Int), (bytes, bytes)) def zscan(self, key, cursor, *args): - return self._scan(key.value.items, cursor, *args) + new_cursor, ans = self._scan(key.value.items(), cursor, *args) + flat = [] + for (key, score) in ans: + flat.append(key) + flat.append(Float.encode(score, False)) + return [new_cursor, flat] @command((Key(ZSet), bytes)) def zscore(self, key, member): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fakeredis-1.0.4/fakeredis.egg-info/PKG-INFO new/fakeredis-1.0.5/fakeredis.egg-info/PKG-INFO --- old/fakeredis-1.0.4/fakeredis.egg-info/PKG-INFO 2019-08-14 11:55:44.000000000 +0200 +++ new/fakeredis-1.0.5/fakeredis.egg-info/PKG-INFO 2019-09-05 11:51:08.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: fakeredis -Version: 1.0.4 +Version: 1.0.5 Summary: Fake implementation of redis API for testing purposes. Home-page: https://github.com/jamesls/fakeredis Author: James Saryerwinnie @@ -233,7 +233,6 @@ * object * restore * touch - * unlink * wait @@ -381,6 +380,12 @@ Revision history ================ + 1.0.5 + ----- + - `#247 <https://github.com/jamesls/fakeredis/pull/247>`_ Support NX/XX/CH flags in ZADD command + - `#250 <https://github.com/jamesls/fakeredis/pull/250>`_ Implement UNLINK command + - `#252 <https://github.com/jamesls/fakeredis/pull/252>`_ Fix implementation of ZSCAN + 1.0.4 ----- - `#240 <https://github.com/jamesls/fakeredis/issues/240>`_ `#242 <https://github.com/jamesls/fakeredis/issues/242>`_ Support for ``redis==3.3`` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fakeredis-1.0.4/setup.py new/fakeredis-1.0.5/setup.py --- old/fakeredis-1.0.4/setup.py 2019-08-14 11:30:03.000000000 +0200 +++ new/fakeredis-1.0.5/setup.py 2019-09-05 11:50:42.000000000 +0200 @@ -5,7 +5,7 @@ setup( name='fakeredis', - version='1.0.4', + version='1.0.5', description="Fake implementation of redis API for testing purposes.", long_description=open(os.path.join(os.path.dirname(__file__), 'README.rst')).read(), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fakeredis-1.0.4/test_fakeredis.py new/fakeredis-1.0.5/test_fakeredis.py --- old/fakeredis-1.0.4/test_fakeredis.py 2019-08-14 11:11:33.000000000 +0200 +++ new/fakeredis-1.0.5/test_fakeredis.py 2019-09-05 11:34:50.000000000 +0200 @@ -1,5 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +from collections import namedtuple from time import sleep, time from redis.exceptions import ResponseError import inspect @@ -26,6 +27,9 @@ REDIS3 = int(redis.__version__.split('.')[0]) >= 3 +UpdateCommand = namedtuple('UpdateCommand', 'input expected_return_value expected_state') + + def redis_must_be_running(cls): # This can probably be improved. This will determines # at import time if the tests should be run, but we probably @@ -104,9 +108,9 @@ self.redis.response_callbacks = response_callbacks # Wrap some redis commands to abstract differences between redis-py 2 and 3. - def zadd(self, key, d): + def zadd(self, key, d, *args, **kwargs): if REDIS3: - return self.redis.zadd(key, d) + return self.redis.zadd(key, d, *args, **kwargs) else: return self.redis.zadd(key, **d) @@ -1806,6 +1810,129 @@ self.assertEqual(self.redis.zrange('foo', 1, 1), [b'two']) + @redis3_only + def test_zadd_with_nx(self): + self.zadd('foo', {'four': 4.0, 'three': 3.0}) + + updates = [ + UpdateCommand( + input={'four': 2.0, 'three': 1.0}, + expected_return_value=0, + expected_state=[(b'four', 4.0), (b'three', 3.0)]), + UpdateCommand( + input={'four': 2.0, 'three': 1.0, 'zero': 0.0}, + expected_return_value=1, + expected_state=[(b'four', 4.0), (b'three', 3.0), (b'zero', 0.0)]), + UpdateCommand( + input={'two': 2.0, 'one': 1.0}, + expected_return_value=2, + expected_state=[(b'four', 4.0), (b'three', 3.0), (b'two', 2.0), (b'one', 1.0), (b'zero', 0.0)]), + ] + + for update in updates: + self.assertEqual(self.zadd('foo', update.input, nx=True), update.expected_return_value) + self.assertItemsEqual(self.redis.zrange('foo', 0, -1, withscores=True), update.expected_state) + + @redis3_only + def test_zadd_with_ch(self): + self.zadd('foo', {'four': 4.0, 'three': 3.0}) + + updates = [ + UpdateCommand( + input={'four': 4.0, 'three': 1.0}, + expected_return_value=1, + expected_state=[(b'four', 4.0), (b'three', 1.0)]), + UpdateCommand( + input={'four': 4.0, 'three': 3.0, 'zero': 0.0}, + expected_return_value=2, + expected_state=[(b'four', 4.0), (b'three', 3.0), (b'zero', 0.0)]), + UpdateCommand( + input={'two': 2.0, 'one': 1.0}, + expected_return_value=2, + expected_state=[(b'four', 4.0), (b'three', 3.0), (b'two', 2.0), (b'one', 1.0), (b'zero', 0.0)]), + ] + + for update in updates: + self.assertEqual(self.zadd('foo', update.input, ch=True), update.expected_return_value) + self.assertItemsEqual(self.redis.zrange('foo', 0, -1, withscores=True), update.expected_state) + + @redis3_only + def test_zadd_with_xx(self): + self.zadd('foo', {'four': 4.0, 'three': 3.0}) + + updates = [ + UpdateCommand( + input={'four': 2.0, 'three': 1.0}, + expected_return_value=0, + expected_state=[(b'four', 2.0), (b'three', 1.0)]), + UpdateCommand( + input={'four': 4.0, 'three': 3.0, 'zero': 0.0}, + expected_return_value=0, + expected_state=[(b'four', 4.0), (b'three', 3.0)]), + UpdateCommand( + input={'two': 2.0, 'one': 1.0}, + expected_return_value=0, + expected_state=[(b'four', 4.0), (b'three', 3.0)]), + ] + + for update in updates: + self.assertEqual(self.zadd('foo', update.input, xx=True), update.expected_return_value) + self.assertItemsEqual(self.redis.zrange('foo', 0, -1, withscores=True), update.expected_state) + + @redis3_only + def test_zadd_with_nx_and_xx(self): + self.zadd('foo', {'four': 4.0, 'three': 3.0}) + with self.assertRaises(redis.DataError): + self.zadd('foo', {'four': -4.0, 'three': -3.0}, nx=True, xx=True) + with self.assertRaises(redis.DataError): + self.zadd('foo', {'four': -4.0, 'three': -3.0}, nx=True, xx=True, ch=True) + + @redis3_only + def test_zadd_with_nx_and_ch(self): + self.zadd('foo', {'four': 4.0, 'three': 3.0}) + + updates = [ + UpdateCommand( + input={'four': 2.0, 'three': 1.0}, + expected_return_value=0, + expected_state=[(b'four', 4.0), (b'three', 3.0)]), + UpdateCommand( + input={'four': 2.0, 'three': 1.0, 'zero': 0.0}, + expected_return_value=1, + expected_state=[(b'four', 4.0), (b'three', 3.0), (b'zero', 0.0)]), + UpdateCommand( + input={'two': 2.0, 'one': 1.0}, + expected_return_value=2, + expected_state=[(b'four', 4.0), (b'three', 3.0), (b'two', 2.0), (b'one', 1.0), (b'zero', 0.0)]), + ] + + for update in updates: + self.assertEqual(self.zadd('foo', update.input, nx=True, ch=True), update.expected_return_value) + self.assertItemsEqual(self.redis.zrange('foo', 0, -1, withscores=True), update.expected_state) + + @redis3_only + def test_zadd_with_xx_and_ch(self): + self.zadd('foo', {'four': 4.0, 'three': 3.0}) + + updates = [ + UpdateCommand( + input={'four': 2.0, 'three': 1.0}, + expected_return_value=2, + expected_state=[(b'four', 2.0), (b'three', 1.0)]), + UpdateCommand( + input={'four': 4.0, 'three': 3.0, 'zero': 0.0}, + expected_return_value=2, + expected_state=[(b'four', 4.0), (b'three', 3.0)]), + UpdateCommand( + input={'two': 2.0, 'one': 1.0}, + expected_return_value=0, + expected_state=[(b'four', 4.0), (b'three', 3.0)]), + ] + + for update in updates: + self.assertEqual(self.zadd('foo', update.input, xx=True, ch=True), update.expected_return_value) + self.assertItemsEqual(self.redis.zrange('foo', 0, -1, withscores=True), update.expected_state) + def test_zrange_same_score(self): self.zadd('foo', {'two_a': 2}) self.zadd('foo', {'two_b': 2}) @@ -3472,6 +3599,27 @@ self.assertIn(b'key:17', results) self.assertEqual(2, len(results)) + def test_zscan(self): + # Setup the data + name = 'zscan-test' + for ix in range(20): + self.zadd(name, {'key:%s' % ix: ix}) + expected = dict(self.redis.zrange(name, 0, -1, withscores=True)) + + # Test the basic version + results = {} + for key, val in self.redis.zscan_iter(name, count=6): + results[key] = val + self.assertEqual(expected, results) + + # Now test that the MATCH functionality works + results = {} + cursor = '0' + while cursor != 0: + cursor, data = self.redis.zscan(name, cursor, match='*7', count=6) + results.update(data) + self.assertEqual(results, {b'key:7': 7.0, b'key:17': 17.0}) + @attr('slow') def test_set_ex_should_expire_value(self): self.redis.set('foo', 'bar') @@ -4016,6 +4164,12 @@ result = script(args=[42]) self.assertEqual(result, b'42') + @redis3_only + def test_unlink(self): + self.redis.set('foo', 'bar') + self.redis.unlink('foo') + self.assertIsNone(self.redis.get('foo')) + class TestFakeRedis(unittest.TestCase): decode_responses = False diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fakeredis-1.0.4/test_fakeredis_hypothesis.py new/fakeredis-1.0.5/test_fakeredis_hypothesis.py --- old/fakeredis-1.0.4/test_fakeredis_hypothesis.py 2019-08-14 11:00:30.000000000 +0200 +++ new/fakeredis-1.0.5/test_fakeredis_hypothesis.py 2019-08-26 08:55:35.000000000 +0200 @@ -155,7 +155,7 @@ # TODO: all expiry-related commands common_commands = ( - commands(st.sampled_from(['del', 'persist', 'type']), keys) + commands(st.sampled_from(['del', 'persist', 'type', 'unlink']), keys) | commands(st.just('exists'), st.lists(keys)) | commands(st.just('keys'), st.just('*')) # Disabled for now due to redis giving wrong answers @@ -279,8 +279,10 @@ commands(st.just('zadd'), keys, st.lists(st.tuples(scores, fields), min_size=1)) ) zset_commands = ( - # TODO: test xx, nx, ch, incr - commands(st.just('zadd'), keys, st.lists(st.tuples(scores, fields))) + # TODO: test incr + commands(st.just('zadd'), keys, st.none() | st.just('nx'), + st.none() | st.just('xx'), st.none() | st.just('ch'), + st.lists(st.tuples(scores, fields))) | commands(st.just('zcard'), keys) | commands(st.just('zcount'), keys, score_tests, score_tests) | commands(st.just('zincrby'), keys, scores, fields) @@ -306,8 +308,10 @@ commands(st.just('zadd'), keys, st.lists(st.tuples(st.just(0), fields), min_size=1)) ) zset_no_score_commands = ( - # TODO: test xx, nx, ch, incr - commands(st.just('zadd'), keys, st.lists(st.tuples(st.just(0), fields))) + # TODO: test incr + commands(st.just('zadd'), keys, st.none() | st.just('nx'), + st.none() | st.just('xx'), st.none() | st.just('ch'), + st.lists(st.tuples(st.just(0), fields))) | commands(st.just('zlexcount'), keys, string_tests, string_tests) | commands(st.sampled_from(['zrangebylex', 'zrevrangebylex']), keys, string_tests, string_tests, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fakeredis-1.0.4/tox.ini new/fakeredis-1.0.5/tox.ini --- old/fakeredis-1.0.4/tox.ini 2019-01-24 10:47:02.000000000 +0100 +++ new/fakeredis-1.0.5/tox.ini 2019-08-14 12:08:41.000000000 +0200 @@ -1,5 +1,6 @@ [tox] -envlist = py27,py34,py35,py36,py3.7 +envlist = + py{27,34,35,36,37,py} [testenv] usedevelop = True