From 72ae25a9c2bb1a9e369e52e696a8b7d1a8df245e Mon Sep 17 00:00:00 2001 From: ar3ph <192461522+ar3ph@users.noreply.github.com> Date: Mon, 2 Feb 2026 13:26:18 -0500 Subject: [PATCH] Fixed #36879 -- Identified Django client in Redis client metadata. --- AUTHORS | 1 + django/core/cache/backends/redis.py | 15 ++++++++++++++- tests/cache/tests.py | 19 +++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 1896dad908..597fe7991b 100644 --- a/AUTHORS +++ b/AUTHORS @@ -113,6 +113,7 @@ answer newbie questions, and generally made Django that much better: Anubhav Joshi Anvesh Mishra Anže Pečar + ar3ph A. Rafey Khan Aram Dulyan arien diff --git a/django/core/cache/backends/redis.py b/django/core/cache/backends/redis.py index bbf070a375..727ea51f84 100644 --- a/django/core/cache/backends/redis.py +++ b/django/core/cache/backends/redis.py @@ -4,6 +4,7 @@ import pickle import random import re +import django from django.core.cache.backends.base import DEFAULT_TIMEOUT, BaseCache from django.utils.functional import cached_property from django.utils.module_loading import import_string @@ -59,7 +60,19 @@ class RedisCacheClient: parser_class = import_string(parser_class) parser_class = parser_class or self._lib.connection.DefaultParser - self._pool_options = {"parser_class": parser_class, **options} + version = django.get_version() + if hasattr(self._lib, "DriverInfo"): + driver_info = self._lib.DriverInfo().add_upstream_driver("django", version) + driver_info_options = {"driver_info": driver_info} + else: + # DriverInfo is not available in this redis-py version. + driver_info_options = {"lib_name": f"redis-py(django_v{version})"} + + self._pool_options = { + "parser_class": parser_class, + **driver_info_options, + **options, + } def _get_connection_pool_index(self, write): # Write to the first server. Read from other servers if there are more, diff --git a/tests/cache/tests.py b/tests/cache/tests.py index db5df20701..b36e3a6a06 100644 --- a/tests/cache/tests.py +++ b/tests/cache/tests.py @@ -15,6 +15,7 @@ from functools import wraps from pathlib import Path from unittest import mock, skipIf +import django from django.conf import settings from django.core import management, signals from django.core.cache import ( @@ -1986,6 +1987,24 @@ class RedisCacheTests(BaseCacheTests, TestCase): self.assertEqual(pool.connection_kwargs["socket_timeout"], 0.1) self.assertIs(pool.connection_kwargs["retry_on_timeout"], True) + def test_client_driver_info(self): + client_info = cache._cache.get_client().client_info() + if {"lib-name", "lib-ver"}.issubset(client_info): + version = django.get_version() + if hasattr(self.lib, "DriverInfo"): + info = self._lib.DriverInfo().add_upstream_driver("django", version) + correct_lib_name = info.formatted_name + else: + correct_lib_name = f"redis-py(django_v{version})" + # Relax the assertion to allow date variance in editable installs. + truncated_lib_name = correct_lib_name.rsplit(".dev", maxsplit=1)[0] + self.assertIn(truncated_lib_name, client_info["lib-name"]) + self.assertEqual(client_info["lib-ver"], self.lib.__version__) + else: + # Redis versions below 7.2 lack CLIENT SETINFO. + self.assertNotIn("lib-ver", client_info) + self.assertNotIn("lib-name", client_info) + class FileBasedCachePathLibTests(FileBasedCacheTests): def mkdtemp(self):