Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change pickle default version to Python default instead of highest version #555

Merged
merged 1 commit into from
Oct 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
26 changes: 26 additions & 0 deletions tests/test_serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import pickle

import pytest
from django.core.exceptions import ImproperlyConfigured

from django_redis.serializers.pickle import PickleSerializer


class TestPickleSerializer:
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})