summaryrefslogtreecommitdiff
path: root/requests_cache/serializers
diff options
context:
space:
mode:
authorJordan Cook <jordan.cook@pioneer.com>2022-02-15 14:04:39 -0600
committerJordan Cook <jordan.cook@pioneer.com>2022-02-15 14:09:04 -0600
commitb5bac5aae0213b44fe02e362ece9d4ef60ff8793 (patch)
tree88284b25c4d769080ce63bb58e456e46d57745ff /requests_cache/serializers
parent43c9287b26cefde75b4e22d974b616f9675e4960 (diff)
downloadrequests-cache-b5bac5aae0213b44fe02e362ece9d4ef60ff8793.tar.gz
Fix serialization in filesystem backend with binary content that is also valid UTF-8
Diffstat (limited to 'requests_cache/serializers')
-rw-r--r--requests_cache/serializers/pipeline.py24
-rw-r--r--requests_cache/serializers/preconf.py17
2 files changed, 25 insertions, 16 deletions
diff --git a/requests_cache/serializers/pipeline.py b/requests_cache/serializers/pipeline.py
index 3bbfbda..2a22761 100644
--- a/requests_cache/serializers/pipeline.py
+++ b/requests_cache/serializers/pipeline.py
@@ -3,7 +3,7 @@
:classes-only:
:nosignatures:
"""
-from typing import Any, Callable, List, Union
+from typing import Any, Callable, Sequence, Union
from ..models import CachedResponse
@@ -29,22 +29,26 @@ class Stage:
class SerializerPipeline:
- """A sequence of steps used to serialize and deserialize response objects.
- This can be initialized with :py:class:`Stage` objects, or any objects with ``dumps()`` and
- ``loads()`` methods
+ """A pipeline of stages chained together to serialize and deserialize response objects.
+
+ Args:
+ stages: A sequence of :py:class:`Stage` objects, or any objects with ``dumps()`` and
+ ``loads()`` methods
+ is_binary: Indicates whether the serialized content is binary
"""
- def __init__(self, stages: List):
- self.steps = stages
- self.dump_steps = [step.dumps for step in stages]
- self.load_steps = [step.loads for step in reversed(stages)]
+ def __init__(self, stages: Sequence, is_binary: bool = False):
+ self.is_binary = is_binary
+ self.stages = stages
+ self.dump_stages = [stage.dumps for stage in stages]
+ self.load_stages = [stage.loads for stage in reversed(stages)]
def dumps(self, value) -> Union[str, bytes]:
- for step in self.dump_steps:
+ for step in self.dump_stages:
value = step(value)
return value
def loads(self, value) -> CachedResponse:
- for step in self.load_steps:
+ for step in self.load_stages:
value = step(value)
return value
diff --git a/requests_cache/serializers/preconf.py b/requests_cache/serializers/preconf.py
index 6cf83bc..35453b5 100644
--- a/requests_cache/serializers/preconf.py
+++ b/requests_cache/serializers/preconf.py
@@ -34,7 +34,9 @@ orjson_preconf_stage = CattrStage(orjson.make_converter) #: Pre-serialization s
yaml_preconf_stage = CattrStage(pyyaml.make_converter) #: Pre-serialization steps for YAML
toml_preconf_stage = CattrStage(tomlkit.make_converter) #: Pre-serialization steps for TOML
ujson_preconf_stage = CattrStage(ujson.make_converter) #: Pre-serialization steps for ultrajson
-pickle_serializer = SerializerPipeline([base_stage, pickle]) #: Complete pickle serializer
+pickle_serializer = SerializerPipeline(
+ [base_stage, pickle], is_binary=True
+) #: Complete pickle serializer
utf8_encoder = Stage(dumps=str.encode, loads=lambda x: x.decode()) #: Encode to bytes
@@ -55,7 +57,9 @@ try:
"""Create a serializer that uses ``pickle`` + ``itsdangerous`` to add a signature to
responses on write, and validate that signature with a secret key on read.
"""
- return SerializerPipeline([base_stage, pickle, signer_stage(secret_key, salt)])
+ return SerializerPipeline(
+ [base_stage, pickle, signer_stage(secret_key, salt)], is_binary=True
+ )
except ImportError as e:
signer_stage = get_placeholder_class(e)
@@ -70,8 +74,8 @@ try:
import bson
bson_serializer = SerializerPipeline(
- [bson_preconf_stage, bson]
- ) #: Complete BSON serializer; using pymongo's ``bson.json_util`` if installed, otherwise standalone ``bson`` codec
+ [bson_preconf_stage, bson], is_binary=False
+ ) #: Complete BSON serializer; uses pymongo's ``bson.json_util`` if installed, otherwise standalone ``bson`` codec
except ImportError as e:
bson_serializer = get_placeholder_class(e)
@@ -88,7 +92,7 @@ except ImportError:
_json_stage = Stage(dumps=partial(json.dumps, indent=2), loads=json.loads)
json_serializer = SerializerPipeline(
- [_json_preconf_stage, _json_stage]
+ [_json_preconf_stage, _json_stage], is_binary=False
) #: Complete JSON serializer; uses ultrajson if available
@@ -100,7 +104,8 @@ try:
[
yaml_preconf_stage,
Stage(yaml, loads='safe_load', dumps='safe_dump'),
- ]
+ ],
+ is_binary=False,
) #: Complete YAML serializer
except ImportError as e:
yaml_serializer = get_placeholder_class(e)