Skip to content

Commit

Permalink
Change pickle default version to Python default instead of Highest ve…
Browse files Browse the repository at this point in the history
…rsion
  • Loading branch information
dizhakbot committed Oct 14, 2021
1 parent 80f791b commit a894611
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 4 deletions.
6 changes: 3 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -193,16 +193,16 @@ Pickle version

For almost all values, django-redis uses pickle to serialize objects.

The latest available version of pickle is used by default. If you want set a
concrete version, you can do it, using ``PICKLE_VERSION`` option:
The ``pickle.DEFAULT_PROTOCOL`` version of pickle is used by default to ensure safe upgrades and compatibility across Python versions.
If you want set a concrete version, you can do it, using ``PICKLE_VERSION`` option:

.. code-block:: python
CACHES = {
"default": {
# ...
"OPTIONS": {
"PICKLE_VERSION": -1 # Use the latest protocol version
"PICKLE_VERSION": -1 # Will use highest protocol version available
}
}
}
Expand Down
7 changes: 6 additions & 1 deletion django_redis/serializers/pickle.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

class PickleSerializer(BaseSerializer):
def __init__(self, options) -> None:
self._pickle_version = -1
self._pickle_version = pickle.DEFAULT_PROTOCOL
self.setup_pickle_version(options)

super().__init__(options=options)
Expand All @@ -17,6 +17,11 @@ def setup_pickle_version(self, options) -> None:
if "PICKLE_VERSION" in options:
try:
self._pickle_version = int(options["PICKLE_VERSION"])
if self._pickle_version > pickle.HIGHEST_PROTOCOL:
raise ImproperlyConfigured(
f"PICKLE_VERSION can't be higher than pickle.HIGHEST_PROTOCOL:"
f" {pickle.HIGHEST_PROTOCOL}"
)
except (ValueError, TypeError):
raise ImproperlyConfigured("PICKLE_VERSION value must be an integer")

Expand Down
39 changes: 39 additions & 0 deletions tests/test_serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import pickle
import sys

import pytest
from django.core.exceptions import ImproperlyConfigured

from django_redis.serializers.pickle import PickleSerializer


class TestPickleSerializer:
@pytest.mark.skipif(
sys.version_info < (3, 8),
reason="Protocol 5 was added as highest from python version 3.8",
)
def test_using_negative_protocol_value(self):
serializer_p5 = PickleSerializer({"PICKLE_VERSION": pickle.HIGHEST_PROTOCOL})
p5_data = serializer_p5.dumps({"key": "value"})

serializer_test = PickleSerializer({"PICKLE_VERSION": -1})
test_data = serializer_test.dumps({"key": "value"})
assert p5_data == test_data

def test_invalid_pickle_version_provided(self):
with pytest.raises(
ImproperlyConfigured, match="PICKLE_VERSION value must be an integer"
):
PickleSerializer({"PICKLE_VERSION": "not-an-integer"})

def test_setup_pickle_version_not_explicitly_specified(self):
serializer = PickleSerializer({})
assert serializer._pickle_version == pickle.DEFAULT_PROTOCOL

def test_setup_pickle_version_too_high(self):
with pytest.raises(
ImproperlyConfigured,
match=f"PICKLE_VERSION can't be higher than pickle.HIGHEST_PROTOCOL:"
f" {pickle.HIGHEST_PROTOCOL}",
):
PickleSerializer({"PICKLE_VERSION": pickle.HIGHEST_PROTOCOL + 1})

0 comments on commit a894611

Please sign in to comment.