diff options
author | Jordan Cook <jordan.cook@pioneer.com> | 2022-02-15 14:04:39 -0600 |
---|---|---|
committer | Jordan Cook <jordan.cook@pioneer.com> | 2022-02-15 14:09:04 -0600 |
commit | b5bac5aae0213b44fe02e362ece9d4ef60ff8793 (patch) | |
tree | 88284b25c4d769080ce63bb58e456e46d57745ff /requests_cache/serializers | |
parent | 43c9287b26cefde75b4e22d974b616f9675e4960 (diff) | |
download | requests-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.py | 24 | ||||
-rw-r--r-- | requests_cache/serializers/preconf.py | 17 |
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) |