@@ -452,12 +452,14 @@ def parse(tokens: typing.List[Token], p: float = 0) -> "Object":
452452
453453
454454OBJECT_DESERIALIZERS : Dict [str , FunctionType ] = {}
455+ OBJECT_TYPES : Dict [str , type ] = {}
455456
456457
457458@dataclass (eq = True , frozen = True , unsafe_hash = True )
458459class Object :
459460 def __init_subclass__ (cls , / , ** kwargs : Dict [Any , Any ]) -> None :
460461 super ().__init_subclass__ (** kwargs )
462+ OBJECT_TYPES [cls .__name__ ] = cls
461463 deserializer = cls .__dict__ .get ("deserialize" , None )
462464 if deserializer :
463465 assert isinstance (deserializer , staticmethod )
@@ -488,13 +490,23 @@ def deserialize(msg: Dict[str, Any]) -> "Object":
488490 ty = msg ["type" ]
489491 assert isinstance (ty , str )
490492 deserializer = OBJECT_DESERIALIZERS .get (ty )
491- if not deserializer :
492- raise NotImplementedError (f"unknown type { ty } " )
493- result = deserializer (msg )
493+ if deserializer :
494+ result = deserializer (msg )
495+ assert isinstance (result , Object )
496+ return result
497+ cls = OBJECT_TYPES [ty ]
498+ kwargs = {}
499+ for field in dataclasses .fields (cls ):
500+ if issubclass (field .type , Object ):
501+ kwargs [field .name ] = Object .deserialize (msg [field .name ])
502+ else :
503+ raise NotImplementedError ("deserializing non-Object fields; write your own deserialize function" )
504+ result = cls (** kwargs )
494505 assert isinstance (result , Object )
495506 return result
496507
497508
509+
498510@dataclass (eq = True , frozen = True , unsafe_hash = True )
499511class Int (Object ):
500512 value : int
@@ -672,34 +684,12 @@ class Function(Object):
672684 arg : Object
673685 body : Object
674686
675- @staticmethod
676- def deserialize (msg : Dict [str , object ]) -> "Function" :
677- assert msg ["type" ] == "Function"
678- arg_obj = msg ["arg" ]
679- assert isinstance (arg_obj , dict )
680- arg = Object .deserialize (arg_obj )
681- body_obj = msg ["body" ]
682- assert isinstance (body_obj , dict )
683- body = Object .deserialize (body_obj )
684- return Function (arg , body )
685-
686687
687688@dataclass (eq = True , frozen = True , unsafe_hash = True )
688689class Apply (Object ):
689690 func : Object
690691 arg : Object
691692
692- @staticmethod
693- def deserialize (msg : Dict [str , object ]) -> "Apply" :
694- assert msg ["type" ] == "Apply"
695- func_obj = msg ["func" ]
696- assert isinstance (func_obj , dict )
697- func = Object .deserialize (func_obj )
698- arg_obj = msg ["arg" ]
699- assert isinstance (arg_obj , dict )
700- arg = Object .deserialize (arg_obj )
701- return Apply (func , arg )
702-
703693
704694@dataclass (eq = True , frozen = True , unsafe_hash = True )
705695class Compose (Object ):
0 commit comments