Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-django-redis for
openSUSE:Factory checked in at 2023-07-03 17:42:15
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-django-redis (Old)
and /work/SRC/openSUSE:Factory/.python-django-redis.new.13546 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-django-redis"
Mon Jul 3 17:42:15 2023 rev:12 rq:1096317 version:5.3.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-django-redis/python-django-redis.changes
2023-06-26 18:17:01.802719908 +0200
+++
/work/SRC/openSUSE:Factory/.python-django-redis.new.13546/python-django-redis.changes
2023-07-03 17:42:17.280542871 +0200
@@ -1,0 +2,19 @@
+Sat Jul 1 20:30:43 UTC 2023 - Dirk Müller <[email protected]>
+
+- update to 5.3.0:
+ * Add support for django 4
+ * Access `django_redis.cache.DJANGO_REDIS_SCAN_ITERSIZE` and
+ `django_redis.client.herd.CACHE_HERD_TIMEOUT` in runtime to
+ not read Django settings in import time.
+ * Skipping pickle serializer test for django >= 4.2
+ * Speed up deleting multiple keys by a pattern with pipelines
+ and larger itersize
+ * Print full exception traceback when logging ignored
+ exceptions
+ * Fix mypy linting
+ * Added support for python 3.11
+ * Fix CI, running tox<4 to still support Python 3.6.
+ * Dropped support for django 2.2 and 3.1
+ * Run actions & tox against Django 4..2
+
+-------------------------------------------------------------------
Old:
----
django-redis-5.2.0.tar.gz
New:
----
django-redis-5.3.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-django-redis.spec ++++++
--- /var/tmp/diff_new_pack.BWqMFN/_old 2023-07-03 17:42:17.968546922 +0200
+++ /var/tmp/diff_new_pack.BWqMFN/_new 2023-07-03 17:42:17.972546945 +0200
@@ -18,7 +18,7 @@
%{?sle15_python_module_pythons}
Name: python-django-redis
-Version: 5.2.0
+Version: 5.3.0
Release: 0
Summary: A redis cache backend for Django
License: BSD-3-Clause
++++++ django-redis-5.2.0.tar.gz -> django-redis-5.3.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-redis-5.2.0/AUTHORS.rst
new/django-redis-5.3.0/AUTHORS.rst
--- old/django-redis-5.2.0/AUTHORS.rst 2021-12-22 16:08:32.000000000 +0100
+++ new/django-redis-5.3.0/AUTHORS.rst 2023-06-16 14:12:53.000000000 +0200
@@ -1,10 +1,10 @@
Andrei Antoukh / niwibe <https://github.com/niwibe>
-Sean Bleier <http://github.com/sebleier>
-Matt Dennewitz <http://github.com/blackbrrr>
-Jannis Leidel <http://github.com/jezdez>
-S. Angel / Twidi <http://github.com/twidi>
-Noah Kantrowitz / coderanger <http://github.com/coderanger>
-Martin Mahner / bartTC <http://github.com/bartTC>
+Sean Bleier <https://github.com/sebleier>
+Matt Dennewitz <https://github.com/blackbrrr>
+Jannis Leidel <https://github.com/jezdez>
+S. Angel / Twidi <https://github.com/twidi>
+Noah Kantrowitz / coderanger <https://github.com/coderanger>
+Martin Mahner / bartTC <https://github.com/bartTC>
Timothée Peignier / cyberdelia <https://github.com/cyberdelia>
Lior Sion / liorsion <https://github.com/liorsion>
Ales Zoulek / aleszoulek <https://github.com/aleszoulek>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-redis-5.2.0/PKG-INFO
new/django-redis-5.3.0/PKG-INFO
--- old/django-redis-5.2.0/PKG-INFO 2021-12-22 16:08:41.102405300 +0100
+++ new/django-redis-5.3.0/PKG-INFO 2023-06-16 14:13:06.367214400 +0200
@@ -1,19 +1,18 @@
Metadata-Version: 2.1
Name: django-redis
-Version: 5.2.0
+Version: 5.3.0
Summary: Full featured redis cache backend for Django.
Home-page: https://github.com/jazzband/django-redis
Author: Andrei Antoukh
Author-email: [email protected]
License: BSD-3-Clause
-Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Framework :: Django
-Classifier: Framework :: Django :: 2.2
-Classifier: Framework :: Django :: 3.1
Classifier: Framework :: Django :: 3.2
Classifier: Framework :: Django :: 4.0
+Classifier: Framework :: Django :: 4.1
+Classifier: Framework :: Django :: 4.2
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
@@ -25,6 +24,7 @@
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Utilities
Requires-Python: >=3.6
@@ -518,6 +518,15 @@
>>> from django.core.cache import cache
>>> cache.delete_pattern("foo_*")
+To achieve the best performance while deleting many keys, you should set
``DJANGO_REDIS_SCAN_ITERSIZE`` to a relatively
+high number (e.g., 100_000) by default in Django settings or pass it directly
to the ``delete_pattern``.
+
+
+.. code-block:: pycon
+
+ >>> from django.core.cache import cache
+ >>> cache.delete_pattern("foo_*", itersize=100_000)
+
Redis native commands
~~~~~~~~~~~~~~~~~~~~~
@@ -837,7 +846,7 @@
^^^^^^^^^^^
This pluggable client helps dealing with the thundering herd problem. You can
read more about it
-on link: `Wikipedia <http://en.wikipedia.org/wiki/Thundering_herd_problem>`_
+on link: `Wikipedia <https://en.wikipedia.org/wiki/Thundering_herd_problem>`_
Like previous pluggable clients, it inherits all functionality from the
default client, adding some
additional methods for getting/setting keys.
@@ -897,7 +906,7 @@
}
}
-.. _MsgPack: http://msgpack.org/
+.. _MsgPack: https://msgpack.org/
Pluggable Redis client
~~~~~~~~~~~~~~~~~~~~~~
@@ -997,5 +1006,3 @@
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-redis-5.2.0/README.rst
new/django-redis-5.3.0/README.rst
--- old/django-redis-5.2.0/README.rst 2021-12-22 16:08:32.000000000 +0100
+++ new/django-redis-5.3.0/README.rst 2023-06-16 14:12:53.000000000 +0200
@@ -483,6 +483,15 @@
>>> from django.core.cache import cache
>>> cache.delete_pattern("foo_*")
+To achieve the best performance while deleting many keys, you should set
``DJANGO_REDIS_SCAN_ITERSIZE`` to a relatively
+high number (e.g., 100_000) by default in Django settings or pass it directly
to the ``delete_pattern``.
+
+
+.. code-block:: pycon
+
+ >>> from django.core.cache import cache
+ >>> cache.delete_pattern("foo_*", itersize=100_000)
+
Redis native commands
~~~~~~~~~~~~~~~~~~~~~
@@ -802,7 +811,7 @@
^^^^^^^^^^^
This pluggable client helps dealing with the thundering herd problem. You can
read more about it
-on link: `Wikipedia <http://en.wikipedia.org/wiki/Thundering_herd_problem>`_
+on link: `Wikipedia <https://en.wikipedia.org/wiki/Thundering_herd_problem>`_
Like previous pluggable clients, it inherits all functionality from the
default client, adding some
additional methods for getting/setting keys.
@@ -862,7 +871,7 @@
}
}
-.. _MsgPack: http://msgpack.org/
+.. _MsgPack: https://msgpack.org/
Pluggable Redis client
~~~~~~~~~~~~~~~~~~~~~~
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-redis-5.2.0/django_redis/__init__.py
new/django-redis-5.3.0/django_redis/__init__.py
--- old/django-redis-5.2.0/django_redis/__init__.py 2021-12-22
16:08:32.000000000 +0100
+++ new/django-redis-5.3.0/django_redis/__init__.py 2023-06-16
14:12:53.000000000 +0200
@@ -1,4 +1,4 @@
-VERSION = (5, 2, 0)
+VERSION = (5, 3, 0)
__version__ = ".".join(map(str, VERSION))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-redis-5.2.0/django_redis/cache.py
new/django-redis-5.3.0/django_redis/cache.py
--- old/django-redis-5.2.0/django_redis/cache.py 2021-12-22
16:08:32.000000000 +0100
+++ new/django-redis-5.3.0/django_redis/cache.py 2023-06-16
14:12:53.000000000 +0200
@@ -9,8 +9,6 @@
from .exceptions import ConnectionInterrupted
-DJANGO_REDIS_SCAN_ITERSIZE = getattr(settings, "DJANGO_REDIS_SCAN_ITERSIZE",
10)
-
CONNECTION_INTERRUPTED = object()
@@ -32,7 +30,7 @@
except ConnectionInterrupted as e:
if self._ignore_exceptions:
if self._log_ignored_exceptions:
- self.logger.error(str(e))
+ self.logger.exception("Exception ignored")
return return_value
raise e.__cause__
@@ -45,6 +43,9 @@
super().__init__(params)
self._server = server
self._params = params
+ self._default_scan_itersize = getattr(
+ settings, "DJANGO_REDIS_SCAN_ITERSIZE", 10
+ )
options = params.get("OPTIONS", {})
self._client_cls = options.get(
@@ -105,7 +106,7 @@
@omit_exception
def delete_pattern(self, *args, **kwargs):
- kwargs["itersize"] = kwargs.get("itersize", DJANGO_REDIS_SCAN_ITERSIZE)
+ kwargs.setdefault("itersize", self._default_scan_itersize)
return self.client.delete_pattern(*args, **kwargs)
@omit_exception
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-redis-5.2.0/django_redis/client/default.py
new/django-redis-5.3.0/django_redis/client/default.py
--- old/django-redis-5.2.0/django_redis/client/default.py 2021-12-22
16:08:32.000000000 +0100
+++ new/django-redis-5.3.0/django_redis/client/default.py 2023-06-16
14:12:53.000000000 +0200
@@ -393,9 +393,13 @@
try:
count = 0
+ pipeline = client.pipeline()
+
for key in client.scan_iter(match=pattern, count=itersize):
- client.delete(key)
+ pipeline.delete(key)
count += 1
+ pipeline.execute()
+
return count
except _main_exceptions as e:
raise ConnectionInterrupted(connection=client) from e
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-redis-5.2.0/django_redis/client/herd.py
new/django-redis-5.3.0/django_redis/client/herd.py
--- old/django-redis-5.2.0/django_redis/client/herd.py 2021-12-22
16:08:32.000000000 +0100
+++ new/django-redis-5.3.0/django_redis/client/herd.py 2023-06-16
14:12:53.000000000 +0200
@@ -21,15 +21,12 @@
pass
-CACHE_HERD_TIMEOUT = getattr(settings, "CACHE_HERD_TIMEOUT", 60)
-
-
-def _is_expired(x):
- if x >= CACHE_HERD_TIMEOUT:
+def _is_expired(x, herd_timeout: int) -> bool:
+ if x >= herd_timeout:
return True
- val = x + random.randint(1, CACHE_HERD_TIMEOUT)
+ val = x + random.randint(1, herd_timeout)
- if val >= CACHE_HERD_TIMEOUT:
+ if val >= herd_timeout:
return True
return False
@@ -37,6 +34,7 @@
class HerdClient(DefaultClient):
def __init__(self, *args, **kwargs):
self._marker = Marker()
+ self._herd_timeout = getattr(settings, "CACHE_HERD_TIMEOUT", 60)
super().__init__(*args, **kwargs)
def _pack(self, value, timeout):
@@ -55,7 +53,7 @@
now = int(time.time())
if herd_timeout < now:
x = now - herd_timeout
- return unpacked, _is_expired(x)
+ return unpacked, _is_expired(x, self._herd_timeout)
return unpacked, False
@@ -69,7 +67,6 @@
nx=False,
xx=False,
):
-
if timeout is DEFAULT_TIMEOUT:
timeout = self._backend.default_timeout
@@ -85,7 +82,7 @@
)
packed = self._pack(value, timeout)
- real_timeout = timeout + CACHE_HERD_TIMEOUT
+ real_timeout = timeout + self._herd_timeout
return super().set(
key, packed, timeout=real_timeout, version=version, client=client,
nx=nx
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-redis-5.2.0/django_redis/client/sharded.py
new/django-redis-5.3.0/django_redis/client/sharded.py
--- old/django-redis-5.2.0/django_redis/client/sharded.py 2021-12-22
16:08:32.000000000 +0100
+++ new/django-redis-5.3.0/django_redis/client/sharded.py 2023-06-16
14:12:53.000000000 +0200
@@ -205,7 +205,6 @@
client=None,
thread_local=True,
):
-
if client is None:
key = self.make_key(key, version=version)
client = self.get_server(key)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-redis-5.2.0/django_redis/pool.py
new/django-redis-5.3.0/django_redis/pool.py
--- old/django-redis-5.2.0/django_redis/pool.py 2021-12-22 16:08:32.000000000
+0100
+++ new/django-redis-5.3.0/django_redis/pool.py 2023-06-16 14:12:53.000000000
+0200
@@ -10,7 +10,6 @@
class ConnectionFactory:
-
# Store connection pool by cache backend options.
#
# _pools is a process-global, as otherwise _pools is cleared every time
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-redis-5.2.0/django_redis.egg-info/PKG-INFO
new/django-redis-5.3.0/django_redis.egg-info/PKG-INFO
--- old/django-redis-5.2.0/django_redis.egg-info/PKG-INFO 2021-12-22
16:08:41.000000000 +0100
+++ new/django-redis-5.3.0/django_redis.egg-info/PKG-INFO 2023-06-16
14:13:06.000000000 +0200
@@ -1,19 +1,18 @@
Metadata-Version: 2.1
Name: django-redis
-Version: 5.2.0
+Version: 5.3.0
Summary: Full featured redis cache backend for Django.
Home-page: https://github.com/jazzband/django-redis
Author: Andrei Antoukh
Author-email: [email protected]
License: BSD-3-Clause
-Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Framework :: Django
-Classifier: Framework :: Django :: 2.2
-Classifier: Framework :: Django :: 3.1
Classifier: Framework :: Django :: 3.2
Classifier: Framework :: Django :: 4.0
+Classifier: Framework :: Django :: 4.1
+Classifier: Framework :: Django :: 4.2
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
@@ -25,6 +24,7 @@
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Utilities
Requires-Python: >=3.6
@@ -518,6 +518,15 @@
>>> from django.core.cache import cache
>>> cache.delete_pattern("foo_*")
+To achieve the best performance while deleting many keys, you should set
``DJANGO_REDIS_SCAN_ITERSIZE`` to a relatively
+high number (e.g., 100_000) by default in Django settings or pass it directly
to the ``delete_pattern``.
+
+
+.. code-block:: pycon
+
+ >>> from django.core.cache import cache
+ >>> cache.delete_pattern("foo_*", itersize=100_000)
+
Redis native commands
~~~~~~~~~~~~~~~~~~~~~
@@ -837,7 +846,7 @@
^^^^^^^^^^^
This pluggable client helps dealing with the thundering herd problem. You can
read more about it
-on link: `Wikipedia <http://en.wikipedia.org/wiki/Thundering_herd_problem>`_
+on link: `Wikipedia <https://en.wikipedia.org/wiki/Thundering_herd_problem>`_
Like previous pluggable clients, it inherits all functionality from the
default client, adding some
additional methods for getting/setting keys.
@@ -897,7 +906,7 @@
}
}
-.. _MsgPack: http://msgpack.org/
+.. _MsgPack: https://msgpack.org/
Pluggable Redis client
~~~~~~~~~~~~~~~~~~~~~~
@@ -997,5 +1006,3 @@
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/django-redis-5.2.0/django_redis.egg-info/requires.txt
new/django-redis-5.3.0/django_redis.egg-info/requires.txt
--- old/django-redis-5.2.0/django_redis.egg-info/requires.txt 2021-12-22
16:08:41.000000000 +0100
+++ new/django-redis-5.3.0/django_redis.egg-info/requires.txt 2023-06-16
14:13:06.000000000 +0200
@@ -1,4 +1,4 @@
-Django>=2.2
+Django>=3.2
redis!=4.0.0,!=4.0.1,>=3
[hiredis]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-redis-5.2.0/setup.cfg
new/django-redis-5.3.0/setup.cfg
--- old/django-redis-5.2.0/setup.cfg 2021-12-22 16:08:41.102405300 +0100
+++ new/django-redis-5.3.0/setup.cfg 2023-06-16 14:13:06.371214400 +0200
@@ -12,10 +12,10 @@
Development Status :: 5 - Production/Stable
Environment :: Web Environment
Framework :: Django
- Framework :: Django :: 2.2
- Framework :: Django :: 3.1
Framework :: Django :: 3.2
Framework :: Django :: 4.0
+ Framework :: Django :: 4.1
+ Framework :: Django :: 4.2
Intended Audience :: Developers
License :: OSI Approved :: BSD License
Operating System :: OS Independent
@@ -27,6 +27,7 @@
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
+ Programming Language :: Python :: 3.11
Topic :: Software Development :: Libraries
Topic :: Utilities
@@ -38,7 +39,7 @@
django_redis.serializers
django_redis.compressors
install_requires =
- Django>=2.2
+ Django>=3.2
redis>=3,!=4.0.0,!=4.0.1
[options.extras_require]
@@ -70,9 +71,9 @@
flake8
isort
mypy
- py{36,37,38,39,310}-dj{22,31,32,40}-redislatest
- py310-dj40-redismaster
- py310-djmain-redis{latest,master}
+ py{36,37,38,39,310,311}-dj{22,31,32,40,41,42}-redislatest
+ py311-dj42-redismaster
+ py311-djmain-redis{latest,master}
[gh-actions]
python =
@@ -81,13 +82,14 @@
3.8: py38, black, flake8, isort, mypy
3.9: py39
3.10: py310
+ 3.11: py311
[gh-actions:env]
DJANGO =
- 2.2: dj22
- 3.1: dj31
3.2: dj32
4.0: dj40
+ 4.1: dj41
+ 4.2: dj42
main: djmain
REDIS =
latest: redislatest
@@ -97,6 +99,7 @@
passenv = CI GITHUB*
commands =
{envpython} -m pytest --cov-report= --ds=settings.sqlite {posargs}
+ {envpython} -m pytest --cov-append --cov-report=
--ds=settings.sqlite_herd {posargs}
{envpython} -m pytest --cov-append --cov-report=
--ds=settings.sqlite_json {posargs}
{envpython} -m pytest --cov-append --cov-report=
--ds=settings.sqlite_lz4 {posargs}
{envpython} -m pytest --cov-append --cov-report=
--ds=settings.sqlite_msgpack {posargs}
@@ -108,10 +111,10 @@
{envpython} -m coverage report
{envpython} -m coverage xml
deps =
- dj22: Django>=2.2,<2.3
- dj31: Django>=3.1,<3.2
dj32: Django>=3.2,<3.3
dj40: Django>=4.0,<4.1
+ dj41: Django>=4.1,<4.2
+ dj42: Django>=4.2,<5.0
djmain: https://github.com/django/django/archive/main.tar.gz
msgpack>=0.6.0
pytest
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-redis-5.2.0/tests/conftest.py
new/django-redis-5.3.0/tests/conftest.py
--- old/django-redis-5.2.0/tests/conftest.py 2021-12-22 16:08:32.000000000
+0100
+++ new/django-redis-5.3.0/tests/conftest.py 2023-06-16 14:12:53.000000000
+0200
@@ -3,10 +3,10 @@
import pytest
from django.core.cache import cache as default_cache
-from django_redis.cache import RedisCache
+from django_redis.cache import BaseCache
@pytest.fixture
-def cache() -> Iterable[RedisCache]:
+def cache() -> Iterable[BaseCache]:
yield default_cache
default_cache.clear()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-redis-5.2.0/tests/settings/sqlite_herd.py
new/django-redis-5.3.0/tests/settings/sqlite_herd.py
--- old/django-redis-5.2.0/tests/settings/sqlite_herd.py 2021-12-22
16:08:32.000000000 +0100
+++ new/django-redis-5.3.0/tests/settings/sqlite_herd.py 2023-06-16
14:12:53.000000000 +0200
@@ -27,3 +27,5 @@
INSTALLED_APPS = ["django.contrib.sessions"]
USE_TZ = False
+
+CACHE_HERD_TIMEOUT = 2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-redis-5.2.0/tests/test_backend.py
new/django-redis-5.3.0/tests/test_backend.py
--- old/django-redis-5.2.0/tests/test_backend.py 2021-12-22
16:08:32.000000000 +0100
+++ new/django-redis-5.3.0/tests/test_backend.py 2023-06-16
14:12:53.000000000 +0200
@@ -2,21 +2,29 @@
import threading
import time
from datetime import timedelta
-from typing import List, Union, cast
+from typing import Iterable, List, Union, cast
from unittest.mock import patch
import pytest
from django.core.cache import caches
+from django.test import override_settings
from pytest_django.fixtures import SettingsWrapper
from pytest_mock import MockerFixture
-import django_redis.cache
from django_redis.cache import RedisCache
from django_redis.client import ShardClient, herd
from django_redis.serializers.json import JSONSerializer
from django_redis.serializers.msgpack import MSGPackSerializer
-herd.CACHE_HERD_TIMEOUT = 2
+
[email protected]
+def patch_itersize_setting() -> Iterable[None]:
+ # destroy cache to force recreation with overriden settings
+ del caches["default"]
+ with override_settings(DJANGO_REDIS_SCAN_ITERSIZE=30):
+ yield
+ # destroy cache to force recreation with original settings
+ del caches["default"]
class TestDjangoRedisCache:
@@ -199,7 +207,12 @@
res = cache.get_many(["a", "b", "c"])
assert res == {"a": 1, "b": 2, "c": 3}
- def test_set_call_empty_pipeline(self, cache: RedisCache, mocker:
MockerFixture):
+ def test_set_call_empty_pipeline(
+ self,
+ cache: RedisCache,
+ mocker: MockerFixture,
+ settings: SettingsWrapper,
+ ):
if isinstance(cache.client, ShardClient):
pytest.skip("ShardClient doesn't support get_client")
@@ -212,7 +225,7 @@
if isinstance(cache.client, herd.HerdClient):
default_timeout = cache.client._backend.default_timeout
- herd_timeout = (default_timeout + herd.CACHE_HERD_TIMEOUT) * 1000
+ herd_timeout = (default_timeout + settings.CACHE_HERD_TIMEOUT) *
1000
herd_pack_value = cache.client._pack(value, default_timeout)
mocked_set.assert_called_once_with(
cache.client.make_key(key, version=None),
@@ -495,11 +508,15 @@
@patch("django_redis.cache.RedisCache.client")
def test_delete_pattern_with_settings_default_scan_count(
- self, client_mock, cache: RedisCache
+ self,
+ client_mock,
+ patch_itersize_setting,
+ cache: RedisCache,
+ settings: SettingsWrapper,
):
for key in ["foo-aa", "foo-ab", "foo-bb", "foo-bc"]:
cache.set(key, "foo")
- expected_count = django_redis.cache.DJANGO_REDIS_SCAN_ITERSIZE
+ expected_count = settings.DJANGO_REDIS_SCAN_ITERSIZE
cache.delete_pattern("*foo-a*")
@@ -541,7 +558,6 @@
assert ttl == 0
def test_pttl(self, cache: RedisCache):
-
# Test pttl
cache.set("foo", "bar", 10)
ttl = cache.pttl("foo")
@@ -599,7 +615,6 @@
assert cache.pexpire("not-existent-key", 20500) is False
def test_pexpire_at(self, cache: RedisCache):
-
# Test settings expiration time 1 hour ahead by datetime.
cache.set("foo", "bar", timeout=None)
expiration_time = datetime.datetime.now() + timedelta(hours=1)
@@ -625,7 +640,6 @@
assert cache.pexpire_at("not-existent-key", expiration_time) is False
def test_expire_at(self, cache: RedisCache):
-
# Test settings expiration time 1 hour ahead by datetime.
cache.set("foo", "bar", timeout=None)
expiration_time = datetime.datetime.now() + timedelta(hours=1)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-redis-5.2.0/tests/test_cache_options.py
new/django-redis-5.3.0/tests/test_cache_options.py
--- old/django-redis-5.2.0/tests/test_cache_options.py 2021-12-22
16:08:32.000000000 +0100
+++ new/django-redis-5.3.0/tests/test_cache_options.py 2023-06-16
14:12:53.000000000 +0200
@@ -3,6 +3,7 @@
import pytest
from django.core.cache import caches
+from pytest import LogCaptureFixture
from pytest_django.fixtures import SettingsWrapper
from redis.exceptions import ConnectionError
@@ -22,8 +23,10 @@
def ignore_exceptions_cache(settings: SettingsWrapper) -> RedisCache:
caches_setting = copy.deepcopy(settings.CACHES)
caches_setting["doesnotexist"]["OPTIONS"]["IGNORE_EXCEPTIONS"] = True
+ caches_setting["doesnotexist"]["OPTIONS"]["LOG_IGNORED_EXCEPTIONS"] = True
settings.CACHES = caches_setting
settings.DJANGO_REDIS_IGNORE_EXCEPTIONS = True
+ settings.DJANGO_REDIS_LOG_IGNORED_EXCEPTIONS = True
return cast(RedisCache, caches["doesnotexist"])
@@ -34,12 +37,22 @@
assert ignore_exceptions_cache.get_many(["key1", "key2", "key3"]) == {}
-def test_get_django_omit_exceptions(ignore_exceptions_cache: RedisCache):
+def test_get_django_omit_exceptions(
+ caplog: LogCaptureFixture, ignore_exceptions_cache: RedisCache
+):
assert ignore_exceptions_cache._ignore_exceptions is True
+ assert ignore_exceptions_cache._log_ignored_exceptions is True
+
assert ignore_exceptions_cache.get("key") is None
assert ignore_exceptions_cache.get("key", "default") == "default"
assert ignore_exceptions_cache.get("key", default="default") == "default"
+ assert len(caplog.records) == 3
+ assert all(
+ record.levelname == "ERROR" and record.msg == "Exception ignored"
+ for record in caplog.records
+ )
+
def test_get_django_omit_exceptions_priority_1(settings: SettingsWrapper):
caches_setting = copy.deepcopy(settings.CACHES)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-redis-5.2.0/tests/test_client.py
new/django-redis-5.3.0/tests/test_client.py
--- old/django-redis-5.2.0/tests/test_client.py 2021-12-22 16:08:32.000000000
+0100
+++ new/django-redis-5.3.0/tests/test_client.py 2023-06-16 14:12:53.000000000
+0200
@@ -1,5 +1,5 @@
from typing import Iterable
-from unittest.mock import Mock, patch
+from unittest.mock import Mock, call, patch
import pytest
from django.core.cache import DEFAULT_CACHE_ALIAS
@@ -104,6 +104,28 @@
count=90210, match=make_pattern_mock.return_value
)
+ @patch("test_client.DefaultClient.make_pattern")
+ @patch("test_client.DefaultClient.get_client", return_value=Mock())
+ @patch("test_client.DefaultClient.__init__", return_value=None)
+ def test_delete_pattern_calls_pipeline_delete_and_execute(
+ self, init_mock, get_client_mock, make_pattern_mock
+ ):
+ client = DefaultClient()
+ client._backend = Mock()
+ client._backend.key_prefix = ""
+ get_client_mock.return_value.scan_iter.return_value = [":1:foo",
":1:foo-a"]
+ get_client_mock.return_value.pipeline.return_value = Mock()
+ get_client_mock.return_value.pipeline.return_value.delete = Mock()
+ get_client_mock.return_value.pipeline.return_value.execute = Mock()
+
+ client.delete_pattern(pattern="foo*")
+
+ assert
get_client_mock.return_value.pipeline.return_value.delete.call_count == 2
+
get_client_mock.return_value.pipeline.return_value.delete.assert_has_calls(
+ [call(":1:foo"), call(":1:foo-a")]
+ )
+
get_client_mock.return_value.pipeline.return_value.execute.assert_called_once()
+
class TestShardClient:
@patch("test_client.DefaultClient.make_pattern")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-redis-5.2.0/tests/test_session.py
new/django-redis-5.3.0/tests/test_session.py
--- old/django-redis-5.2.0/tests/test_session.py 2021-12-22
16:08:32.000000000 +0100
+++ new/django-redis-5.3.0/tests/test_session.py 2023-06-16
14:12:53.000000000 +0200
@@ -3,6 +3,8 @@
from datetime import timedelta
from typing import Optional, Type
+import django
+import pytest
from django.conf import settings
from django.contrib.sessions.backends.base import SessionBase
from django.contrib.sessions.backends.cache import SessionStore as CacheSession
@@ -365,6 +367,10 @@
class SessionTests(SessionTestsMixin, unittest.TestCase):
backend = CacheSession
+ @pytest.mark.skipif(
+ django.VERSION >= (4, 2),
+ reason="PickleSerializer is removed as of
https://code.djangoproject.com/ticket/29708", # noqa: E501
+ )
def test_actual_expiry(self):
if isinstance(
caches[DEFAULT_CACHE_ALIAS].client._serializer, MSGPackSerializer