Description
Describe the bug
When trying to update our app from redis-py==3.5.3
to redis-py==4.2.0
we stumbled onto a problem. While it only started breaking with the new redis-py version, I believe it's actually a bug here in django-redis
. This also happens with any version of redis-py>=4.0.2
.
I'm happy to provide a PR if this is seen as a bug.
I see in DefaultClient.encode
that we have special behaviour where everything that isinstance(obj, int)
will not be passed through the serializer (pickle in our case) or the compressor. In DefaultClient.decode
we just try int(value)
to bypass deserialization and decompression for these.
The problem is: for models.IntegerChoices
and an integer-enum (see example) instance(enum_variant, int) is True
. This then leads to a text representation of the enum being stored in redis (something like <Values1.CHOICE_1: 1>
), which of course cannot be converted back to an integer via int()
. And also it cannot be decoded with pickle.
The diff between 3.5.3 and 4.0.2 is huge ( redis/redis-py@3.5.3...v4.0.2 ) and I couldn't directly see why this worked before, but I believe our encode/decode mapping is in the wrong here.
To Reproduce
This is with a default django-redis setup.
With models.IntegerChoices
:
from django.core.cache import cache
from django.db import models
class Values1(models.IntegerChoices):
CHOICE_1 = 1
CHOICE_2 = 2
cache.set("key", Values1.CHOICE_1)
# this breaks with :
# UnpicklingError: invalid load key, '<'.
cache.get("key")
With a python standard int-enum:
import enum
from django.core.cache import cache
class Values2(int, enum.Enum):
SOMETHING_1 = 1
SOMETHING_2 = 2
cache.set("key", Values2.SOMETHING_1)
# this breaks with :
# UnpicklingError: invalid load key, '<'.
cache.get("key")
Expected behavior
I would expect the enum-variant to be cached and returned as enum-variant.
Stack trace
I don't think we need this, I'm happy to provide one if needed.
Environment (please complete the following information):
- Python version: 3.9.12
- Django Redis Version: 5.2.0
- Django Version: 3.2.12
- Redis Version: [e.g. 2.5.0]
- redis-py Version: 4.2.0
Additional context
Add any other context about the problem here.