Skip to content

Commit d2d91c3

Browse files
Make BaseSerializer abstract (#624)
1 parent cb7df4c commit d2d91c3

File tree

4 files changed

+40
-37
lines changed

4 files changed

+40
-37
lines changed

aiocache/serializers/serializers.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import logging
22
import pickle # noqa: S403
3+
from abc import ABC, abstractmethod
34
from typing import Any, Optional
45

56
logger = logging.getLogger(__name__)
@@ -20,7 +21,7 @@
2021
_NOT_SET = object()
2122

2223

23-
class BaseSerializer:
24+
class BaseSerializer(ABC):
2425

2526
DEFAULT_ENCODING: Optional[str] = "utf-8"
2627

@@ -29,12 +30,14 @@ def __init__(self, *args, encoding=_NOT_SET, **kwargs):
2930
super().__init__(*args, **kwargs)
3031

3132
# TODO(PY38): Positional-only
32-
def dumps(self, value: Any) -> str:
33-
raise NotImplementedError("dumps method must be implemented")
33+
@abstractmethod
34+
def dumps(self, value: Any) -> Any:
35+
"""Serialise the value to be stored in the backend."""
3436

3537
# TODO(PY38): Positional-only
36-
def loads(self, value: str) -> Any:
37-
raise NotImplementedError("loads method must be implemented")
38+
@abstractmethod
39+
def loads(self, value: Any) -> Any:
40+
"""Decode the value retrieved from the backend."""
3841

3942

4043
class NullSerializer(BaseSerializer):

examples/marshmallow_serializer_class.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import random
22
import string
33
import asyncio
4+
from typing import Any
45

56
from marshmallow import fields, Schema, post_load
67

@@ -21,16 +22,12 @@ def __eq__(self, obj):
2122
return self.__dict__ == obj.__dict__
2223

2324

24-
class MarshmallowSerializer(Schema, BaseSerializer): # type: ignore[misc]
25+
class RandomSchema(Schema):
2526
int_type = fields.Integer()
2627
str_type = fields.String()
2728
dict_type = fields.Dict()
2829
list_type = fields.List(fields.Integer())
2930

30-
# marshmallow Schema class doesn't play nicely with multiple inheritance and won't call
31-
# BaseSerializer.__init__
32-
encoding = 'utf-8'
33-
3431
@post_load
3532
def build_my_type(self, data, **kwargs):
3633
return RandomModel(**data)
@@ -39,6 +36,18 @@ class Meta:
3936
strict = True
4037

4138

39+
class MarshmallowSerializer(BaseSerializer):
40+
def __init__(self, *args: Any, **kwargs: Any):
41+
super().__init__(*args, **kwargs)
42+
self.schema = RandomSchema()
43+
44+
def dumps(self, value: Any) -> str:
45+
return self.schema.dumps(value)
46+
47+
def loads(self, value: str) -> Any:
48+
return self.schema.loads(value)
49+
50+
4251
cache = Cache(serializer=MarshmallowSerializer(), namespace="main")
4352

4453

tests/acceptance/test_serializers.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import pickle
22
import random
3+
from typing import Any
34

45
import pytest
56
from marshmallow import Schema, fields, post_load
@@ -29,15 +30,8 @@ def __eq__(self, obj):
2930
return self.__dict__ == obj.__dict__
3031

3132

32-
class MyTypeSchema(Schema, BaseSerializer):
33+
class MySchema(Schema):
3334
r = fields.Integer()
34-
encoding = "utf-8"
35-
36-
def dumps(self, *args, **kwargs):
37-
return super().dumps(*args, **kwargs)
38-
39-
def loads(self, *args, **kwargs):
40-
return super().loads(*args, **kwargs)
4135

4236
@post_load
4337
def build_my_type(self, data, **kwargs):
@@ -47,6 +41,18 @@ class Meta:
4741
strict = True
4842

4943

44+
class MyTypeSchema(BaseSerializer):
45+
def __init__(self, *args: Any, **kwargs: Any):
46+
super().__init__(*args, **kwargs)
47+
self.schema = MySchema()
48+
49+
def dumps(self, value: Any) -> str:
50+
return self.schema.dumps(value)
51+
52+
def loads(self, value: str) -> Any:
53+
return self.schema.loads(value)
54+
55+
5056
class TestNullSerializer:
5157
TYPES = (1, 2.0, "hi", True, ["1", 1], {"key": "value"}, MyType())
5258

tests/ut/test_serializers.py

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,33 +20,18 @@
2020
JSON_TYPES = [1, 2.0, "hi", True, ["1", 1], {"key": "value"}]
2121

2222

23-
class TestBaseSerializer:
23+
class TestNullSerializer:
2424
def test_init(self):
25-
serializer = BaseSerializer()
25+
serializer = NullSerializer()
26+
assert isinstance(serializer, BaseSerializer)
2627
assert serializer.DEFAULT_ENCODING == "utf-8"
2728
assert serializer.encoding == "utf-8"
2829

2930
def test_init_encoding(self):
30-
serializer = BaseSerializer(encoding="whatever")
31+
serializer = NullSerializer(encoding="whatever")
3132
assert serializer.DEFAULT_ENCODING == "utf-8"
3233
assert serializer.encoding == "whatever"
3334

34-
def test_dumps(self):
35-
with pytest.raises(NotImplementedError):
36-
BaseSerializer().dumps("")
37-
38-
def test_loads(self):
39-
with pytest.raises(NotImplementedError):
40-
BaseSerializer().loads("")
41-
42-
43-
class TestNullSerializer:
44-
def test_init(self):
45-
serializer = NullSerializer()
46-
assert isinstance(serializer, BaseSerializer)
47-
assert serializer.DEFAULT_ENCODING == "utf-8"
48-
assert serializer.encoding == "utf-8"
49-
5035
@pytest.mark.parametrize("obj", TYPES)
5136
def test_set_types(self, obj):
5237
assert NullSerializer().dumps(obj) is obj

0 commit comments

Comments
 (0)