python-dataclasses-serialization
python-dataclasses-serialization copied to clipboard
Add deserializer for Enum
You can add a generic serializer which works for all Enums like so
@JSONSerializer.register_serializer(Enum)
def Enum_serializer(obj: Enum) -> str:
return obj.name
@JSONSerializer.register_deserializer(Enum)
def Enum_deserializer(cls, name: str) -> Enum:
try:
return cls[name]
except KeyError:
raise DeserializationError()
Maybe add this to default JSONSerializer or point to it in the docs?
Example test:
from dataclasses import dataclass
from enum import Enum, auto
from typing import Optional
from unittest import TestCase
from dataclasses_serialization.json import JSONSerializer
from dataclasses_serialization.serializer_base import DeserializationError
class Gender(Enum):
male = auto()
female = auto()
@dataclass(frozen=True)
class Employee:
name: Optional[str]
gender: Optional[Gender]
@JSONSerializer.register_serializer(Enum)
def Enum_serializer(obj: Enum) -> str:
return obj.name
@JSONSerializer.register_deserializer(Enum)
def Enum_deserializer(cls, name: str) -> Enum:
try:
return cls[name]
except KeyError:
raise DeserializationError()
class TestEmployee(TestCase):
def testSerializingNone(self):
emp = Employee(None, None)
resDict = JSONSerializer.serialize(emp)
emp2 = JSONSerializer.deserialize(Employee, resDict)
self.assertEqual(emp, emp2)
def testSerializingValue(self):
emp = Employee("Sarah", Gender.female)
resDict = JSONSerializer.serialize(emp)
emp2 = JSONSerializer.deserialize(Employee, resDict)
self.assertEqual(emp, emp2)
I'd happily include this as an enum_name_serializer
/deserializer
utility function (indeed, I have some suspiciously similar code in my personal projects), but I'm against including it by default in JSONSerializer
as it's not a canonical serialization.
You could equally well serialize an Enum
by its value
, or even its index in definition order.
I rewrote this same feature and came to submit a PR only to find @kitschen already suggested it. A supported utility function would be great.
Would be nice to have this included by default. I'd vote for serialising the value rather than the name, as it allows you to refactor without breaking existing serialised files.