Package: serial-json
Easily add custom JSON serializationCode ExampleDefaultsimportserial_jsonasjsonimportdatetimevalue=b'Hello World!'# Bytes are not supported by json normallyassertjson.loads(json.dumps(value))==valuedt=datetime.datetime.now()# datetimes are not supported by json normallyassertjson.loads(json.dumps(dt))==dtCustomCustom serialization using a classes __getstate__ and __setstate__ methods.importserial_jsonasjson@json.registerclassMyClass(object):def__init__(self,x=0,y=0):self.x=xself.y=ydef__eq__(self,other):"""Compare objects."""try:returnself.x==other.xandself.y==other.yexcept(AttributeError,Exception):returnFalsedef__getstate__(self):return{'x':self.x,'y':self.y}def__setstate__(self,state):self.x=state.get('x',0)self.y=state.get('y',0)my_value=MyClass()assertjson.loads(json.dumps(my_value))==my_valueCustom serialization with functions instead of a class with getstate and setstate.importserial_jsonclassMyClass(object):def__init__(self,x=0,y=0):self.x=xself.y=ydef__eq__(self,other):"""Compare objects."""try:returnself.x==other.xandself.y==other.yexcept(AttributeError,Exception):returnFalsedefcls_to_dict(obj):return{'x':obj.x,'y':obj.y}defcls_from_dict(obj):returnMyClass(**obj)# Register the serialize and deserialize functionsserial_json.register(MyClass,cls_to_dict,cls_from_dict)my_value=MyClass()assertserial_json.loads(serial_json.dumps(my_value))==my_valuedataclassDataclasses can be used through inheritance withDataClassor through the decoratordataclass.importserial_jsonfromserial_jsonimportdataclass,field_property,field@dataclassclassPoint:x:inty:intz:int=field(default=0,skip_repr=0,skip_dict=0)# Do not include in repr if value is 0help(Point)# p = Point()  # Raises error for required positional argumentsp=Point(1,2)assertp.x==1assertp.y==2assertp.z==0classLocation(serial_json.DataClass):name:strpoint:Point=Point(0,0,0)@field_property(default=Point(1,1,0))defpoint2(self):returnself._point2@point2.setterdefpoint2(self,value):ifisinstance(value,(list,tuple))andlen(value)>=2:value=Point(*value)elifisinstance(value,dict):value=Point(**value)ifnotisinstance(value,Point):raiseTypeError('Given value must be a Point!')self._point2=valuehelp(Location)l=Location('hello')assertl.name=='hello'assertl.point==Point(0,0,0)assertl.point2==Point(1,1,0)l2=Location('111',point=Point(x=1,y=1,z=1),point2=(2,2,0))assertl2.name=='111'assertl2.point==Point(1,1,1)assertl2.point2==Point(2,2,0)assertstr(l2)=='Location(name=111, point=Point(x=1, y=1, z=1), point2=Point(x=2, y=2))'# skip reprdatetime propertyAdditional datetime, date, time, and weekdays properties are availableimportdatetimefromserial_jsonimportdataclass,datetime_property,Weekdays,weekdays_property,weekdays_attr_property@dataclassclassItem:created_on:datetime.datetime=datetime_property('created_on',default_factory=datetime.datetime.now)weekdays:Weekdays=weekdays_property('weekdays',default=Weekdays())sunday=weekdays_attr_property('weekdays','sunday')monday=weekdays_attr_property('weekdays','monday')tuesday=weekdays_attr_property('weekdays','tuesday')wednesday=weekdays_attr_property('weekdays','wednesday')thursday=weekdays_attr_property('weekdays','thursday')friday=weekdays_attr_property('weekdays','friday')saturday=weekdays_attr_property('weekdays','saturday')it=Item(weekdays='monday')assertit.created_onisnotNoneassertit.created_on>=datetime.datetime.today().replace(hour=0)assert'monday'init.weekdaysassert'sunday'notinit.weekdaysassertit.mondayassertnotit.sundayit=Item(weekdays=[],friday=True)assertit.created_onisnotNoneassertit.created_on>=datetime.datetime.today().replace(hour=0)assert'friday'init.weekdaysassert'sunday'notinit.weekdaysassertit.fridayassertnotit.sundayit=Item(sunday=False)assertit.created_onisnotNoneassertit.created_on>=datetime.datetime.today().replace(hour=0)assert'friday'init.weekdays,it.weekdaysassert'sunday'notinit.weekdays,it.weekdaysassertit.fridayassertnotit.sunday