Skip to content

Commit 0faf404

Browse files
committed
Make it easier to deserialize classes with only Object fields
Handle this directly in Object.deserialize.
1 parent 2e02c22 commit 0faf404

File tree

1 file changed

+15
-25
lines changed

1 file changed

+15
-25
lines changed

scrapscript.py

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -452,12 +452,14 @@ def parse(tokens: typing.List[Token], p: float = 0) -> "Object":
452452

453453

454454
OBJECT_DESERIALIZERS: Dict[str, FunctionType] = {}
455+
OBJECT_TYPES: Dict[str, type] = {}
455456

456457

457458
@dataclass(eq=True, frozen=True, unsafe_hash=True)
458459
class 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)
499511
class 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)
688689
class 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)
705695
class Compose(Object):

0 commit comments

Comments
 (0)