Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-fakeredis for
openSUSE:Factory checked in at 2022-02-03 23:16:20
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-fakeredis (Old)
and /work/SRC/openSUSE:Factory/.python-fakeredis.new.1898 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-fakeredis"
Thu Feb 3 23:16:20 2022 rev:7 rq:950047 version:1.7.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-fakeredis/python-fakeredis.changes
2021-10-20 20:23:45.349358501 +0200
+++
/work/SRC/openSUSE:Factory/.python-fakeredis.new.1898/python-fakeredis.changes
2022-02-03 23:17:00.248400757 +0100
@@ -1,0 +2,11 @@
+Sun Jan 23 20:36:18 UTC 2022 - Dirk M??ller <[email protected]>
+
+- update to 1.7.0
+ * Change a number of corner-case behaviours to match Redis 6.2.6.
+ * Fix DeprecationWarning for sampling from a set
+ * Improved support for constructor arguments
+ * Support redis-py 4
+ * Add support for GET option to SET
+ * PERSIST and EXPIRE should invalidate watches
+
+-------------------------------------------------------------------
Old:
----
fakeredis-1.6.1.tar.gz
New:
----
fakeredis-1.7.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-fakeredis.spec ++++++
--- /var/tmp/diff_new_pack.4G2W0P/_old 2022-02-03 23:17:00.804396961 +0100
+++ /var/tmp/diff_new_pack.4G2W0P/_new 2022-02-03 23:17:00.812396906 +0100
@@ -1,7 +1,7 @@
#
# spec file for package python-fakeredis
#
-# Copyright (c) 2021 SUSE LLC
+# Copyright (c) 2022 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
%define skip_python2 1
Name: python-fakeredis
-Version: 1.6.1
+Version: 1.7.0
Release: 0
Summary: Fake implementation of redis API for testing purposes
License: BSD-3-Clause AND MIT
++++++ fakeredis-1.6.1.tar.gz -> fakeredis-1.7.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/fakeredis-1.6.1/.github/workflows/test.yml
new/fakeredis-1.7.0/.github/workflows/test.yml
--- old/fakeredis-1.6.1/.github/workflows/test.yml 2021-09-08
17:19:01.000000000 +0200
+++ new/fakeredis-1.7.0/.github/workflows/test.yml 2021-11-23
07:07:12.000000000 +0100
@@ -10,7 +10,7 @@
fail-fast: false
matrix:
python-version: ["3.6", "3.7", "3.8", "3.9", "pypy-3.7"]
- redis-py: ["3.5.3"]
+ redis-py: ["4.0.0"]
aioredis: ["2.0.0"]
include:
- python-version: "3.9"
@@ -35,12 +35,12 @@
redis-py: "3.5.3"
aioredis: "1.3.1"
- python-version: "3.9"
- redis-py: "3.5.*"
+ redis-py: "4.0.*"
aioredis: "2.0.0"
coverage: yes
services:
redis:
- image: redis:6.0.10
+ image: redis:6.2.6
ports:
- 6379:6379
steps:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/fakeredis-1.6.1/PKG-INFO new/fakeredis-1.7.0/PKG-INFO
--- old/fakeredis-1.6.1/PKG-INFO 2021-09-08 17:25:37.496013600 +0200
+++ new/fakeredis-1.7.0/PKG-INFO 2021-11-28 11:39:31.071334000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: fakeredis
-Version: 1.6.1
+Version: 1.7.0
Summary: Fake implementation of redis API for testing purposes.
Home-page: https://github.com/jamesls/fakeredis
Author: James Saryerwinnie
@@ -119,7 +119,7 @@
Fakeredis implements the same interface as `redis-py`_, the
popular redis client for python, and models the responses
-of redis 6.0 (although most new feature in 6.0 are not supported).
+of redis 6.2 (although most new features are not supported).
Support for aioredis
====================
@@ -476,6 +476,15 @@
Revision history
================
+1.7.0
+-----
+- Change a number of corner-case behaviours to match Redis 6.2.6.
+- `#310 <https://github.com/jamesls/fakeredis/pull/310>`_ Fix
DeprecationWarning for sampling from a set
+- `#315 <https://github.com/jamesls/fakeredis/pull/315>`_ Improved support for
constructor arguments
+- `#316 <https://github.com/jamesls/fakeredis/pull/316>`_ Support redis-py 4
+- `#319 <https://github.com/jamesls/fakeredis/pull/319>`_ Add support for GET
option to SET
+- `#323 <https://github.com/jamesls/fakeredis/pull/323>`_ PERSIST and EXPIRE
should invalidate watches
+
1.6.1
-----
- `#305 <https://github.com/jamesls/fakeredis/pull/305>`_ Some packaging
modernisation
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/fakeredis-1.6.1/README.rst
new/fakeredis-1.7.0/README.rst
--- old/fakeredis-1.6.1/README.rst 2021-09-08 17:19:58.000000000 +0200
+++ new/fakeredis-1.7.0/README.rst 2021-11-24 06:54:08.000000000 +0100
@@ -95,7 +95,7 @@
Fakeredis implements the same interface as `redis-py`_, the
popular redis client for python, and models the responses
-of redis 6.0 (although most new feature in 6.0 are not supported).
+of redis 6.2 (although most new features are not supported).
Support for aioredis
====================
@@ -452,6 +452,15 @@
Revision history
================
+1.7.0
+-----
+- Change a number of corner-case behaviours to match Redis 6.2.6.
+- `#310 <https://github.com/jamesls/fakeredis/pull/310>`_ Fix
DeprecationWarning for sampling from a set
+- `#315 <https://github.com/jamesls/fakeredis/pull/315>`_ Improved support for
constructor arguments
+- `#316 <https://github.com/jamesls/fakeredis/pull/316>`_ Support redis-py 4
+- `#319 <https://github.com/jamesls/fakeredis/pull/319>`_ Add support for GET
option to SET
+- `#323 <https://github.com/jamesls/fakeredis/pull/323>`_ PERSIST and EXPIRE
should invalidate watches
+
1.6.1
-----
- `#305 <https://github.com/jamesls/fakeredis/pull/305>`_ Some packaging
modernisation
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/fakeredis-1.6.1/fakeredis/__init__.py
new/fakeredis-1.7.0/fakeredis/__init__.py
--- old/fakeredis-1.6.1/fakeredis/__init__.py 2021-09-06 11:00:58.000000000
+0200
+++ new/fakeredis-1.7.0/fakeredis/__init__.py 2021-11-23 07:07:12.000000000
+0100
@@ -1,4 +1,4 @@
from ._server import FakeServer, FakeRedis, FakeStrictRedis, FakeConnection
# noqa: F401
-__version__ = '1.6.1'
+__version__ = '1.7.0'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/fakeredis-1.6.1/fakeredis/_server.py
new/fakeredis-1.7.0/fakeredis/_server.py
--- old/fakeredis-1.6.1/fakeredis/_server.py 2021-09-06 11:00:58.000000000
+0200
+++ new/fakeredis-1.7.0/fakeredis/_server.py 2021-11-24 06:53:41.000000000
+0100
@@ -1,25 +1,25 @@
+import functools
+import hashlib
+import inspect
+import itertools
import logging
-import time
-import threading
import math
+import pickle
+import queue
import random
import re
+import threading
+import time
import warnings
-import functools
-import itertools
-import hashlib
import weakref
-import queue
-import pickle
from collections import defaultdict
from collections.abc import MutableMapping
-import six
import redis
+import six
from ._zset import ZSet
-
LOGGER = logging.getLogger('fakeredis')
REDIS_LOG_LEVELS = {
b'LOG_DEBUG': 0,
@@ -86,6 +86,9 @@
FLAG_NO_SCRIPT = 's' # Command not allowed in scripts
+# This needs to be grabbed early to avoid breaking tests that mock redis.Redis.
+_ORIG_SIG = inspect.signature(redis.Redis)
+
class SimpleString:
def __init__(self, value):
@@ -240,6 +243,7 @@
def expireat(self, value):
self._expireat = value
self._expireat_modified = True
+ self._modified = True # Since redis 6.0.7
def get(self, default):
return self._value if self else default
@@ -1494,6 +1498,7 @@
xx = False
nx = False
keepttl = False
+ get = False
while i < len(args):
if casematch(args[i], b'nx'):
nx = True
@@ -1503,26 +1508,38 @@
i += 1
elif casematch(args[i], b'ex') and i + 1 < len(args):
ex = Int.decode(args[i + 1])
- if ex <= 0:
+ if ex <= 0 or (self._db.time + ex) * 1000 >= 2**63:
raise SimpleError(INVALID_EXPIRE_MSG.format('set'))
i += 2
elif casematch(args[i], b'px') and i + 1 < len(args):
px = Int.decode(args[i + 1])
- if px <= 0:
+ if px <= 0 or self._db.time * 1000 + px >= 2**63:
raise SimpleError(INVALID_EXPIRE_MSG.format('set'))
i += 2
elif casematch(args[i], b'keepttl'):
keepttl = True
i += 1
+ elif casematch(args[i], b'get'):
+ get = True
+ i += 1
else:
raise SimpleError(SYNTAX_ERROR_MSG)
if (xx and nx) or ((px is not None) + (ex is not None) + keepttl > 1):
raise SimpleError(SYNTAX_ERROR_MSG)
+ if nx and get:
+ # The command docs say this is allowed from Redis 7.0.
+ raise SimpleError(SYNTAX_ERROR_MSG)
+
+ old_value = None
+ if get:
+ if key.value is not None and type(key.value) is not bytes:
+ raise SimpleError(WRONGTYPE_MSG)
+ old_value = key.value
if nx and key:
- return None
+ return old_value
if xx and not key:
- return None
+ return old_value
if not keepttl:
key.value = value
else:
@@ -1531,11 +1548,11 @@
key.expireat = self._db.time + ex
if px is not None:
key.expireat = self._db.time + px / 1000.0
- return OK
+ return OK if not get else old_value
@command((Key(), Int, bytes))
def setex(self, key, seconds, value):
- if seconds <= 0:
+ if seconds <= 0 or (self._db.time + seconds) * 1000 >= 2**63:
raise SimpleError(INVALID_EXPIRE_MSG.format('setex'))
key.value = value
key.expireat = self._db.time + seconds
@@ -1543,7 +1560,7 @@
@command((Key(), Int, bytes))
def psetex(self, key, ms, value):
- if ms <= 0:
+ if ms <= 0 or self._db.time * 1000 + ms >= 2**63:
raise SimpleError(INVALID_EXPIRE_MSG.format('psetex'))
key.value = value
key.expireat = self._db.time + ms / 1000.0
@@ -1754,14 +1771,38 @@
def llen(self, key):
return len(key.value)
- @command((Key(list),))
- def lpop(self, key):
- try:
- ret = key.value.pop(0)
- key.updated()
- return ret
- except IndexError:
+ def _list_pop(self, get_slice, key, *args):
+ """Implements lpop and rpop.
+
+ `get_slice` must take a count and return a slice expression for the
+ range to pop.
+ """
+ # This implementation is somewhat contorted to match the odd
+ # behaviours described in https://github.com/redis/redis/issues/9680.
+ count = 1
+ if len(args) > 1:
+ raise SimpleError(SYNTAX_ERROR_MSG)
+ elif len(args) == 1:
+ count = args[0]
+ if count < 0:
+ raise SimpleError(INDEX_ERROR_MSG)
+ elif count == 0:
+ return None
+ if not key:
return None
+ elif type(key.value) != list:
+ raise SimpleError(WRONGTYPE_MSG)
+ slc = get_slice(count)
+ ret = key.value[slc]
+ del key.value[slc]
+ key.updated()
+ if not args:
+ ret = ret[0]
+ return ret
+
+ @command((Key(),), (Int(),))
+ def lpop(self, key, *args):
+ return self._list_pop(lambda count: slice(None, count), key, *args)
@command((Key(list), bytes), (bytes,))
def lpush(self, key, *values):
@@ -1826,14 +1867,9 @@
key.update(new_value)
return OK
- @command((Key(list),))
- def rpop(self, key):
- try:
- ret = key.value.pop()
- key.updated()
- return ret
- except IndexError:
- return None
+ @command((Key(),), (Int(),))
+ def rpop(self, key, *args):
+ return self._list_pop(lambda count: slice(None, -count - 1, -1), key,
*args)
@command((Key(list, None), Key(list)))
def rpoplpush(self, src, dst):
@@ -1902,13 +1938,11 @@
def sdiffstore(self, dst, *keys):
return self._setop(lambda a, b: a - b, False, dst, *keys)
- # The following keys can't be marked as sets because of the
- # stop_if_empty early-out.
- @command((Key(set),), (Key(),))
+ @command((Key(set),), (Key(set),))
def sinter(self, *keys):
return self._setop(lambda a, b: a & b, True, None, *keys)
- @command((Key(), Key(set)), (Key(),))
+ @command((Key(), Key(set)), (Key(set),))
def sinterstore(self, dst, *keys):
return self._setop(lambda a, b: a & b, True, dst, *keys)
@@ -1937,7 +1971,7 @@
if count is None:
if not key.value:
return None
- item = random.sample(key.value, 1)[0]
+ item = random.sample(list(key.value), 1)[0]
key.value.remove(item)
key.updated()
return item
@@ -1956,10 +1990,10 @@
if not key.value:
return None
else:
- return random.sample(key.value, 1)[0]
+ return random.sample(list(key.value), 1)[0]
elif count >= 0:
count = min(count, len(key.value))
- return random.sample(key.value, count)
+ return random.sample(list(key.value), count)
else:
items = list(key.value)
return [random.choice(items) for _ in range(-count)]
@@ -2131,14 +2165,17 @@
def _zrange(self, key, start, stop, reverse, *args):
zset = key.value
- # TODO: does redis allow multiple WITHSCORES?
- if len(args) > 1 or (args and not casematch(args[0], b'withscores')):
- raise SimpleError(SYNTAX_ERROR_MSG)
+ withscores = False
+ for arg in args:
+ if casematch(arg, b'withscores'):
+ withscores = True
+ else:
+ raise SimpleError(SYNTAX_ERROR_MSG)
start, stop = self._fix_range(start, stop, len(zset))
if reverse:
start, stop = len(zset) - stop, len(zset) - start
items = zset.islice_score(start, stop, reverse)
- items = self._apply_withscores(items, bool(args))
+ items = self._apply_withscores(items, withscores)
return items
@command((Key(ZSet), Int, Int), (bytes,))
@@ -2355,8 +2392,10 @@
# Server commands
# TODO: lots
- @command((), flags='s')
- def bgsave(self):
+ @command((), (bytes,), flags='s')
+ def bgsave(self, *args):
+ if len(args) > 1 or (len(args) == 1 and not casematch(args[0],
b'schedule')):
+ raise SimpleError(SYNTAX_ERROR_MSG)
self._server.lastsave = int(time.time())
return BGSAVE_STARTED
@@ -2493,7 +2532,7 @@
@command((bytes, Int), (bytes,), flags='s')
def eval(self, script, numkeys, *keys_and_args):
- from lupa import LuaRuntime, LuaError, as_attrgetter
+ from lupa import LuaError, LuaRuntime, as_attrgetter
if numkeys > len(keys_and_args):
raise SimpleError(TOO_MANY_KEYS_MSG)
@@ -2560,7 +2599,7 @@
elif casematch(subcmd, b'exists'):
return [int(sha1 in self._server.script_cache) for sha1 in args]
elif casematch(subcmd, b'flush'):
- if len(args) != 0:
+ if len(args) > 1 or (len(args) == 1 and casenorm(args[0]) not in
{b'sync', b'async'}):
raise SimpleError(BAD_SUBCOMMAND_MSG.format('SCRIPT'))
self._server.script_cache = {}
return OK
@@ -2741,73 +2780,63 @@
class FakeRedisMixin:
- def __init__(self, host='localhost', port=6379,
- db=0, password=None, socket_timeout=None,
- socket_connect_timeout=None,
- socket_keepalive=None, socket_keepalive_options=None,
- connection_pool=None, unix_socket_path=None,
- encoding='utf-8', encoding_errors='strict',
- charset=None, errors=None,
- decode_responses=False, retry_on_timeout=False,
- ssl=False, ssl_keyfile=None, ssl_certfile=None,
- ssl_cert_reqs=None, ssl_ca_certs=None,
- max_connections=None, server=None,
- connected=True):
- if not connection_pool:
+ def __init__(self, *args, server=None, connected=True, **kwargs):
+ # Interpret the positional and keyword arguments according to the
+ # version of redis in use.
+ bound = _ORIG_SIG.bind(*args, **kwargs)
+ bound.apply_defaults()
+ if not bound.arguments['connection_pool']:
+ charset = bound.arguments['charset']
+ errors = bound.arguments['errors']
# Adapted from redis-py
if charset is not None:
warnings.warn(DeprecationWarning(
'"charset" is deprecated. Use "encoding" instead'))
- encoding = charset
+ bound.arguments['encoding'] = charset
if errors is not None:
warnings.warn(DeprecationWarning(
'"errors" is deprecated. Use "encoding_errors" instead'))
- encoding_errors = errors
+ bound.arguments['encoding_errors'] = errors
if server is None:
server = FakeServer()
server.connected = connected
kwargs = {
- 'db': db,
- 'password': password,
- 'encoding': encoding,
- 'encoding_errors': encoding_errors,
- 'decode_responses': decode_responses,
- 'max_connections': max_connections,
'connection_class': FakeConnection,
'server': server
}
- connection_pool = redis.connection.ConnectionPool(**kwargs)
- # These need to be passed by name due to
- # https://github.com/andymccurdy/redis-py/issues/1276
- super().__init__(
- host=host, port=port, db=db, password=password,
socket_timeout=socket_timeout,
- socket_connect_timeout=socket_connect_timeout,
- socket_keepalive=socket_keepalive,
- socket_keepalive_options=socket_keepalive_options,
- connection_pool=connection_pool,
- unix_socket_path=unix_socket_path,
- encoding=encoding, encoding_errors=encoding_errors,
- charset=charset, errors=errors,
- decode_responses=decode_responses,
retry_on_timeout=retry_on_timeout,
- ssl=ssl, ssl_keyfile=ssl_keyfile, ssl_certfile=ssl_certfile,
- ssl_cert_reqs=ssl_cert_reqs, ssl_ca_certs=ssl_ca_certs,
- max_connections=max_connections)
+ conn_pool_args = [
+ 'db',
+ 'username',
+ 'password',
+ 'socket_timeout',
+ 'encoding',
+ 'encoding_errors',
+ 'decode_responses',
+ 'retry_on_timeout',
+ 'max_connections',
+ 'health_check_interval',
+ 'client_name'
+ ]
+ for arg in conn_pool_args:
+ if arg in bound.arguments:
+ kwargs[arg] = bound.arguments[arg]
+ bound.arguments['connection_pool'] =
redis.connection.ConnectionPool(**kwargs)
+ super().__init__(*bound.args, **bound.kwargs)
@classmethod
- def from_url(cls, url, db=None, **kwargs):
+ def from_url(cls, *args, **kwargs):
server = kwargs.pop('server', None)
if server is None:
server = FakeServer()
- self = super().from_url(url, db, **kwargs)
+ pool = redis.ConnectionPool.from_url(*args, **kwargs)
# Now override how it creates connections
- pool = self.connection_pool
pool.connection_class = FakeConnection
pool.connection_kwargs['server'] = server
# FakeConnection cannot handle the path kwarg (present when from_url
# is called with a unix socket)
pool.connection_kwargs.pop('path', None)
- return self
+ return cls(connection_pool=pool)
class FakeStrictRedis(FakeRedisMixin, redis.StrictRedis):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/fakeredis-1.6.1/fakeredis.egg-info/PKG-INFO
new/fakeredis-1.7.0/fakeredis.egg-info/PKG-INFO
--- old/fakeredis-1.6.1/fakeredis.egg-info/PKG-INFO 2021-09-08
17:25:37.000000000 +0200
+++ new/fakeredis-1.7.0/fakeredis.egg-info/PKG-INFO 2021-11-28
11:39:31.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: fakeredis
-Version: 1.6.1
+Version: 1.7.0
Summary: Fake implementation of redis API for testing purposes.
Home-page: https://github.com/jamesls/fakeredis
Author: James Saryerwinnie
@@ -119,7 +119,7 @@
Fakeredis implements the same interface as `redis-py`_, the
popular redis client for python, and models the responses
-of redis 6.0 (although most new feature in 6.0 are not supported).
+of redis 6.2 (although most new features are not supported).
Support for aioredis
====================
@@ -476,6 +476,15 @@
Revision history
================
+1.7.0
+-----
+- Change a number of corner-case behaviours to match Redis 6.2.6.
+- `#310 <https://github.com/jamesls/fakeredis/pull/310>`_ Fix
DeprecationWarning for sampling from a set
+- `#315 <https://github.com/jamesls/fakeredis/pull/315>`_ Improved support for
constructor arguments
+- `#316 <https://github.com/jamesls/fakeredis/pull/316>`_ Support redis-py 4
+- `#319 <https://github.com/jamesls/fakeredis/pull/319>`_ Add support for GET
option to SET
+- `#323 <https://github.com/jamesls/fakeredis/pull/323>`_ PERSIST and EXPIRE
should invalidate watches
+
1.6.1
-----
- `#305 <https://github.com/jamesls/fakeredis/pull/305>`_ Some packaging
modernisation
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/fakeredis-1.6.1/fakeredis.egg-info/requires.txt
new/fakeredis-1.7.0/fakeredis.egg-info/requires.txt
--- old/fakeredis-1.6.1/fakeredis.egg-info/requires.txt 2021-09-08
17:25:37.000000000 +0200
+++ new/fakeredis-1.7.0/fakeredis.egg-info/requires.txt 2021-11-28
11:39:31.000000000 +0100
@@ -1,5 +1,5 @@
packaging
-redis<3.6.0
+redis<4.1.0
six>=1.12
sortedcontainers
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/fakeredis-1.6.1/requirements.in
new/fakeredis-1.7.0/requirements.in
--- old/fakeredis-1.6.1/requirements.in 2021-09-08 17:19:01.000000000 +0200
+++ new/fakeredis-1.7.0/requirements.in 2021-11-23 07:07:12.000000000 +0100
@@ -7,7 +7,7 @@
pytest-asyncio
pytest-cov
pytest-mock
-redis==3.5.3 # Latest at time of writing
+redis==4.0.0 # Latest at time of writing
six
sortedcontainers
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/fakeredis-1.6.1/requirements.txt
new/fakeredis-1.7.0/requirements.txt
--- old/fakeredis-1.6.1/requirements.txt 2021-09-08 17:19:01.000000000
+0200
+++ new/fakeredis-1.7.0/requirements.txt 2021-11-23 07:07:12.000000000
+0100
@@ -16,6 +16,8 @@
# via
# -r requirements.in
# pytest-cov
+deprecated==1.2.13
+ # via redis
flake8==3.8.4
# via -r requirements.in
hiredis==1.1.0
@@ -24,7 +26,7 @@
# via -r requirements.in
iniconfig==1.1.1
# via pytest
-lupa==1.9
+lupa==1.10
# via -r requirements.in
mccabe==0.6.1
# via flake8
@@ -40,7 +42,7 @@
# via flake8
pyparsing==2.4.7
# via packaging
-pytest==6.1.2
+pytest==6.2.5
# via
# -r requirements.in
# pytest-asyncio
@@ -52,7 +54,7 @@
# via -r requirements.in
pytest-mock==3.3.1
# via -r requirements.in
-redis==3.5.3
+redis==4.0.0
# via -r requirements.in
six==1.15.0
# via -r requirements.in
@@ -62,5 +64,7 @@
# hypothesis
toml==0.10.2
# via pytest
+wrapt==1.13.3
+ # via deprecated
zipp==1.2.0
# via -r requirements.in
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/fakeredis-1.6.1/setup.cfg
new/fakeredis-1.7.0/setup.cfg
--- old/fakeredis-1.6.1/setup.cfg 2021-09-08 17:25:37.496013600 +0200
+++ new/fakeredis-1.7.0/setup.cfg 2021-11-28 11:39:31.071334000 +0100
@@ -23,7 +23,7 @@
packages = fakeredis
install_requires =
packaging
- redis<3.6.0
+ redis<4.1.0
six>=1.12
sortedcontainers
python_requires = >=3.5
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/fakeredis-1.6.1/test/test_fakeredis.py
new/fakeredis-1.7.0/test/test_fakeredis.py
--- old/fakeredis-1.6.1/test/test_fakeredis.py 2021-09-06 11:00:58.000000000
+0200
+++ new/fakeredis-1.7.0/test/test_fakeredis.py 2021-11-24 06:53:41.000000000
+0100
@@ -709,6 +709,12 @@
r.setex('foo', 1.2, 'bar')
[email protected]_server('6.2')
+def test_setex_overflow(r):
+ with pytest.raises(ResponseError):
+ r.setex('foo', 18446744073709561, 'bar') # Overflows long long in ms
+
+
def test_set_ex(r):
assert r.set('foo', 'bar', ex=100) is True
assert r.get('foo') == b'bar'
@@ -719,6 +725,16 @@
assert r.get('foo') == b'bar'
+def test_set_ex_overflow(r):
+ with pytest.raises(ResponseError):
+ r.set('foo', 'bar', ex=18446744073709561) # Overflows long long in ms
+
+
+def test_set_px_overflow(r):
+ with pytest.raises(ResponseError):
+ r.set('foo', 'bar', px=2**63 - 2) # Overflows after adding current
time
+
+
def test_set_px(r):
assert r.set('foo', 'bar', px=100) is True
assert r.get('foo') == b'bar'
@@ -821,6 +837,38 @@
assert r.set('foo', 'bar', xx=True) is True
[email protected]_server('6.2')
+def test_set_get(r):
+ assert raw_command(r, 'set', 'foo', 'bar', 'GET') is None
+ assert r.get('foo') == b'bar'
+ assert raw_command(r, 'set', 'foo', 'baz', 'GET') == b'bar'
+ assert r.get('foo') == b'baz'
+
+
[email protected]_server('6.2')
+def test_set_get_xx(r):
+ assert raw_command(r, 'set', 'foo', 'bar', 'XX', 'GET') is None
+ assert r.get('foo') is None
+ r.set('foo', 'bar')
+ assert raw_command(r, 'set', 'foo', 'baz', 'XX', 'GET') == b'bar'
+ assert r.get('foo') == b'baz'
+ assert raw_command(r, 'set', 'foo', 'baz', 'GET') == b'baz'
+
+
[email protected]_server('6.2')
+def test_set_get_nx(r):
+ # Note: this will most likely fail on a 7.0 server, based on the docs for
SET
+ with pytest.raises(redis.ResponseError):
+ raw_command(r, 'set', 'foo', 'bar', 'NX', 'GET')
+
+
[email protected]_server('6.2')
+def set_get_wrongtype(r):
+ r.lpush('foo', 'bar')
+ with pytest.raises(redis.ResponseError):
+ raw_command(r, 'set', 'foo', 'bar', 'GET')
+
+
def test_del_operator(r):
r['foo'] = 'bar'
del r['foo']
@@ -1041,6 +1089,22 @@
r.lpop('foo')
[email protected]_server('6.2')
+def test_lpop_count(r):
+ assert r.rpush('foo', 'one') == 1
+ assert r.rpush('foo', 'two') == 2
+ assert r.rpush('foo', 'three') == 3
+ assert raw_command(r, 'lpop', 'foo', 2) == [b'one', b'two']
+ # See https://github.com/redis/redis/issues/9680
+ assert raw_command(r, 'lpop', 'foo', 0) is None
+
+
[email protected]_server('6.2')
+def test_lpop_count_negative(r):
+ with pytest.raises(redis.ResponseError):
+ raw_command(r, 'lpop', 'foo', -1)
+
+
def test_lset(r):
r.rpush('foo', 'one')
r.rpush('foo', 'two')
@@ -1148,6 +1212,22 @@
r.rpop('foo')
[email protected]_server('6.2')
+def test_rpop_count(r):
+ assert r.rpush('foo', 'one') == 1
+ assert r.rpush('foo', 'two') == 2
+ assert r.rpush('foo', 'three') == 3
+ assert raw_command(r, 'rpop', 'foo', 2) == [b'three', b'two']
+ # See https://github.com/redis/redis/issues/9680
+ assert raw_command(r, 'rpop', 'foo', 0) is None
+
+
[email protected]_server('6.2')
+def test_rpop_count_negative(r):
+ with pytest.raises(redis.ResponseError):
+ raw_command(r, 'rpop', 'foo', -1)
+
+
def test_linsert_before(r):
r.rpush('foo', 'hello')
r.rpush('foo', 'world')
@@ -3454,6 +3534,10 @@
def test_bgsave(r):
assert r.bgsave()
+ with pytest.raises(ResponseError):
+ r.execute_command('BGSAVE', 'SCHEDULE', 'FOO')
+ with pytest.raises(ResponseError):
+ r.execute_command('BGSAVE', 'FOO')
def test_lastsave(r):
@@ -4052,6 +4136,18 @@
assert r.expire('bar', 1) is False
+def test_watch_expire(r):
+ """EXPIRE should mark a key as changed for WATCH."""
+ r.set('foo', 'bar')
+ with r.pipeline() as p:
+ p.watch('foo')
+ r.expire('foo', 10000)
+ p.multi()
+ p.get('foo')
+ with pytest.raises(redis.exceptions.WatchError):
+ p.execute()
+
+
@pytest.mark.slow
def test_pexpire_should_expire_key(r):
r.set('foo', 'bar')
@@ -4179,6 +4275,18 @@
assert r.persist('foo') == 0
+def test_watch_persist(r):
+ """PERSIST should mark a variable as changed."""
+ r.set('foo', 'bar', ex=10000)
+ with r.pipeline() as p:
+ p.watch('foo')
+ r.persist('foo')
+ p.multi()
+ p.get('foo')
+ with pytest.raises(redis.exceptions.WatchError):
+ p.execute()
+
+
def test_set_existing_key_persists(r):
r.set('foo', 'bar', ex=20)
r.set('foo', 'foo')
@@ -5004,10 +5112,10 @@
assert db2.get('foo') == b'foo2'
def test_from_url_db_value_error(self):
- # In ValueError, should default to 0
+ # In case of ValueError, should default to 0, or be absent in redis-py
4.0
db = fakeredis.FakeStrictRedis.from_url(
'redis://localhost:6379/a')
- assert db.connection_pool.connection_kwargs['db'] == 0
+ assert db.connection_pool.connection_kwargs.get('db', 0) == 0
def test_can_pass_through_extra_args(self):
db = fakeredis.FakeStrictRedis.from_url(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/fakeredis-1.6.1/test/test_hypothesis.py
new/fakeredis-1.7.0/test/test_hypothesis.py
--- old/fakeredis-1.6.1/test/test_hypothesis.py 2021-03-23 09:27:16.000000000
+0100
+++ new/fakeredis-1.7.0/test/test_hypothesis.py 2021-11-23 07:07:12.000000000
+0100
@@ -204,7 +204,10 @@
| commands(st.just('mget'), st.lists(keys))
| commands(st.sampled_from(['mset', 'msetnx']), st.lists(st.tuples(keys,
values)))
| commands(st.just('set'), keys, values,
- st.none() | st.just('nx'), st.none() | st.just('xx'))
+ st.none() | st.just('nx'),
+ st.none() | st.just('xx'),
+ st.none() | st.just('keepttl'),
+ st.none() | st.just('get'))
| commands(st.just('setex'), keys, expires_seconds, values)
| commands(st.just('psetex'), keys, expires_ms, values)
| commands(st.just('setnx'), keys, values)
@@ -239,7 +242,7 @@
st.sampled_from(['before', 'after', 'BEFORE', 'AFTER']) |
st.binary(),
values, values)
| commands(st.just('llen'), keys)
- | commands(st.sampled_from(['lpop', 'rpop']), keys)
+ | commands(st.sampled_from(['lpop', 'rpop']), keys, st.just(None) |
st.integers())
| commands(st.sampled_from(['lpush', 'lpushx', 'rpush', 'rpushx']), keys,
st.lists(values))
| commands(st.just('lrange'), keys, counts, counts)
| commands(st.just('lrem'), keys, counts, values)