Skip to content

Commit b91ec44

Browse files
committed
Use dict[str, object] instead of dict[bytes, object] in serialization
I don't 100% remember why we did `dict[bytes, object]` (perhaps something to do with the web REPL) but this is much nicer, easier, and cleaner.
1 parent 410cecc commit b91ec44

File tree

1 file changed

+61
-62
lines changed

1 file changed

+61
-62
lines changed

scrapscript.py

Lines changed: 61 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -516,22 +516,19 @@ def __init_subclass__(cls, /, **kwargs: Dict[Any, Any]) -> None:
516516
assert isinstance(func, FunctionType)
517517
OBJECT_DESERIALIZERS[cls.__name__] = func
518518

519-
def serialize(self) -> Dict[bytes, object]:
519+
def serialize(self) -> Dict[str, object]:
520520
cls = type(self)
521-
result: Dict[bytes, object] = {b"type": cls.__name__.encode("utf-8")}
521+
result: Dict[str, object] = {"type": cls.__name__}
522522
for field in dataclasses.fields(cls):
523523
if issubclass(field.type, Object):
524524
value = getattr(self, field.name)
525-
result[field.name.encode("utf-8")] = value.serialize()
525+
result[field.name] = value.serialize()
526526
else:
527527
raise NotImplementedError("serializing non-Object fields; write your own serialize function")
528528
return result
529529

530-
def _serialize(self, **kwargs: object) -> Dict[bytes, object]:
531-
return {
532-
b"type": type(self).__name__.encode("utf-8"),
533-
**{key.encode("utf-8"): value for key, value in kwargs.items()},
534-
}
530+
def _serialize(self, **kwargs: object) -> Dict[str, object]:
531+
return {"type": type(self).__name__, **kwargs}
535532

536533
@staticmethod
537534
def deserialize(msg: Dict[str, Any]) -> "Object":
@@ -562,7 +559,7 @@ def __str__(self) -> str:
562559
class Int(Object):
563560
value: int
564561

565-
def serialize(self) -> Dict[bytes, object]:
562+
def serialize(self) -> Dict[str, object]:
566563
return self._serialize(value=self.value)
567564

568565
@staticmethod
@@ -579,7 +576,7 @@ def __str__(self) -> str:
579576
class Float(Object):
580577
value: float
581578

582-
def serialize(self) -> Dict[bytes, object]:
579+
def serialize(self) -> Dict[str, object]:
583580
raise NotImplementedError("serialization for Float is not supported")
584581

585582
@staticmethod
@@ -594,8 +591,8 @@ def __str__(self) -> str:
594591
class String(Object):
595592
value: str
596593

597-
def serialize(self) -> Dict[bytes, object]:
598-
return {b"type": b"String", b"value": self.value.encode("utf-8")}
594+
def serialize(self) -> Dict[str, object]:
595+
return {"type": "String", "value": self.value}
599596

600597
@staticmethod
601598
def deserialize(msg: Dict[str, object]) -> "String":
@@ -612,8 +609,8 @@ def __str__(self) -> str:
612609
class Bytes(Object):
613610
value: bytes
614611

615-
def serialize(self) -> Dict[bytes, object]:
616-
return {b"type": b"Bytes", b"value": self.value}
612+
def serialize(self) -> Dict[str, object]:
613+
return {"type": "Bytes", "value": str(self)}
617614

618615
@staticmethod
619616
def deserialize(msg: Dict[str, object]) -> "Bytes":
@@ -629,8 +626,8 @@ def __str__(self) -> str:
629626
class Var(Object):
630627
name: str
631628

632-
def serialize(self) -> Dict[bytes, object]:
633-
return {b"type": b"Var", b"name": self.name.encode("utf-8")}
629+
def serialize(self) -> Dict[str, object]:
630+
return {"type": "Var", "name": self.name}
634631

635632
@staticmethod
636633
def deserialize(msg: Dict[str, object]) -> "Var":
@@ -743,12 +740,12 @@ class Binop(Object):
743740
left: Object
744741
right: Object
745742

746-
def serialize(self) -> Dict[bytes, object]:
743+
def serialize(self) -> Dict[str, object]:
747744
return {
748-
b"type": b"Binop",
749-
b"op": self.op.name.encode("utf-8"),
750-
b"left": self.left.serialize(),
751-
b"right": self.right.serialize(),
745+
"type": "Binop",
746+
"op": self.op.name,
747+
"left": self.left.serialize(),
748+
"right": self.right.serialize(),
752749
}
753750

754751
@staticmethod
@@ -774,8 +771,8 @@ def __str__(self) -> str:
774771
class List(Object):
775772
items: typing.List[Object]
776773

777-
def serialize(self) -> Dict[bytes, object]:
778-
return {b"type": b"List", b"items": [item.serialize() for item in self.items]}
774+
def serialize(self) -> Dict[str, object]:
775+
return {"type": "List", "items": [item.serialize() for item in self.items]}
779776

780777
def __str__(self) -> str:
781778
inner = ", ".join(str(item) for item in self.items)
@@ -841,8 +838,8 @@ def __str__(self) -> str:
841838
return self.__repr__()
842839

843840

844-
def serialize_env(env: Env) -> Dict[bytes, object]:
845-
return {key.encode("utf-8"): value.serialize() for key, value in env.items()}
841+
def serialize_env(env: Env) -> Dict[str, object]:
842+
return {key: value.serialize() for key, value in env.items()}
846843

847844

848845
def deserialize_env(msg: Dict[str, Any]) -> Env:
@@ -853,7 +850,7 @@ def deserialize_env(msg: Dict[str, Any]) -> Env:
853850
class EnvObject(Object):
854851
env: Env
855852

856-
def serialize(self) -> Dict[bytes, object]:
853+
def serialize(self) -> Dict[str, object]:
857854
return self._serialize(env=serialize_env(self.env))
858855

859856
@staticmethod
@@ -882,7 +879,7 @@ def __str__(self) -> str:
882879
class MatchFunction(Object):
883880
cases: typing.List[MatchCase]
884881

885-
def serialize(self) -> Dict[bytes, object]:
882+
def serialize(self) -> Dict[str, object]:
886883
return self._serialize(cases=[case.serialize() for case in self.cases])
887884

888885
def __str__(self) -> str:
@@ -894,8 +891,8 @@ def __str__(self) -> str:
894891
class Relocation(Object):
895892
name: str
896893

897-
def serialize(self) -> Dict[bytes, object]:
898-
return self._serialize(name=self.name.encode("utf-8"))
894+
def serialize(self) -> Dict[str, object]:
895+
return self._serialize(name=self.name)
899896

900897
def __str__(self) -> str:
901898
# TODO: Better pretty printing for Relocation
@@ -926,7 +923,7 @@ class NativeFunction(Object):
926923
name: str
927924
func: Callable[[Object], Object]
928925

929-
def serialize(self) -> Dict[bytes, object]:
926+
def serialize(self) -> Dict[str, object]:
930927
return NativeFunctionRelocation(self.name).serialize()
931928

932929
def __str__(self) -> str:
@@ -939,7 +936,7 @@ class Closure(Object):
939936
env: Env
940937
func: Union[Function, MatchFunction]
941938

942-
def serialize(self) -> Dict[bytes, object]:
939+
def serialize(self) -> Dict[str, object]:
943940
return self._serialize(env=serialize_env(self.env), func=self.func.serialize())
944941

945942
@staticmethod
@@ -963,8 +960,8 @@ def __str__(self) -> str:
963960
class Record(Object):
964961
data: Dict[str, Object]
965962

966-
def serialize(self) -> Dict[bytes, object]:
967-
return self._serialize(data={key.encode("utf-8"): value.serialize() for key, value in self.data.items()})
963+
def serialize(self) -> Dict[str, object]:
964+
return self._serialize(data={key: value.serialize() for key, value in self.data.items()})
968965

969966
@staticmethod
970967
def deserialize(msg: Dict[str, object]) -> "Record":
@@ -993,8 +990,8 @@ def __str__(self) -> str:
993990
class Symbol(Object):
994991
value: str
995992

996-
def serialize(self) -> Dict[bytes, object]:
997-
return self._serialize(value=self.value.encode("utf-8"))
993+
def serialize(self) -> Dict[str, object]:
994+
return self._serialize(value=self.value)
998995

999996
@staticmethod
1000997
def deserialize(msg: Dict[str, object]) -> "Symbol":
@@ -1293,6 +1290,8 @@ def bencode(obj: object) -> bytes:
12931290
assert not isinstance(obj, bool)
12941291
if isinstance(obj, int):
12951292
return b"i" + str(int(obj)).encode("ascii") + b"e"
1293+
if isinstance(obj, str):
1294+
return bencode(obj.encode("utf-8"))
12961295
if isinstance(obj, bytes):
12971296
return str(len(obj)).encode("ascii") + b":" + obj
12981297
if isinstance(obj, list):
@@ -3981,11 +3980,11 @@ def test_bdecode_dict_sorts_keys(self) -> None:
39813980
class ObjectSerializeTests(unittest.TestCase):
39823981
def test_serialize_int(self) -> None:
39833982
obj = Int(123)
3984-
self.assertEqual(obj.serialize(), {b"type": b"Int", b"value": 123})
3983+
self.assertEqual(obj.serialize(), {"type": "Int", "value": 123})
39853984

39863985
def test_serialize_negative_int(self) -> None:
39873986
obj = Int(-123)
3988-
self.assertEqual(obj.serialize(), {b"type": b"Int", b"value": -123})
3987+
self.assertEqual(obj.serialize(), {"type": "Int", "value": -123})
39893988

39903989
def test_serialize_float_raises_not_implemented_error(self) -> None:
39913990
obj = Float(3.14)
@@ -3994,65 +3993,65 @@ def test_serialize_float_raises_not_implemented_error(self) -> None:
39943993

39953994
def test_serialize_str(self) -> None:
39963995
obj = String("abc")
3997-
self.assertEqual(obj.serialize(), {b"type": b"String", b"value": b"abc"})
3996+
self.assertEqual(obj.serialize(), {"type": "String", "value": "abc"})
39983997

39993998
def test_serialize_bytes(self) -> None:
40003999
obj = Bytes(b"abc")
4001-
self.assertEqual(obj.serialize(), {b"type": b"Bytes", b"value": b"abc"})
4000+
self.assertEqual(obj.serialize(), {"type": "Bytes", "value": "~~YWJj"})
40024001

40034002
def test_serialize_var(self) -> None:
40044003
obj = Var("abc")
4005-
self.assertEqual(obj.serialize(), {b"type": b"Var", b"name": b"abc"})
4004+
self.assertEqual(obj.serialize(), {"type": "Var", "name": "abc"})
40064005

40074006
def test_serialize_symbol(self) -> None:
40084007
obj = Symbol("true")
4009-
self.assertEqual(obj.serialize(), {b"type": b"Symbol", b"value": b"true"})
4008+
self.assertEqual(obj.serialize(), {"type": "Symbol", "value": "true"})
40104009

40114010
def test_serialize_binary_add(self) -> None:
40124011
obj = Binop(BinopKind.ADD, Int(123), Int(456))
40134012
self.assertEqual(
40144013
obj.serialize(),
40154014
{
4016-
b"left": {b"type": b"Int", b"value": 123},
4017-
b"op": b"ADD",
4018-
b"right": {b"type": b"Int", b"value": 456},
4019-
b"type": b"Binop",
4015+
"left": {"type": "Int", "value": 123},
4016+
"op": "ADD",
4017+
"right": {"type": "Int", "value": 456},
4018+
"type": "Binop",
40204019
},
40214020
)
40224021

40234022
def test_serialize_list(self) -> None:
40244023
obj = List([Int(1), Int(2)])
40254024
self.assertEqual(
40264025
obj.serialize(),
4027-
{b"type": b"List", b"items": [{b"type": b"Int", b"value": 1}, {b"type": b"Int", b"value": 2}]},
4026+
{"type": "List", "items": [{"type": "Int", "value": 1}, {"type": "Int", "value": 2}]},
40284027
)
40294028

40304029
def test_serialize_assign(self) -> None:
40314030
obj = Assign(Var("x"), Int(2))
40324031
self.assertEqual(
40334032
obj.serialize(),
4034-
{b"type": b"Assign", b"name": {b"name": b"x", b"type": b"Var"}, b"value": {b"type": b"Int", b"value": 2}},
4033+
{"type": "Assign", "name": {"name": "x", "type": "Var"}, "value": {"type": "Int", "value": 2}},
40354034
)
40364035

40374036
def test_serialize_record(self) -> None:
40384037
obj = Record({"x": Int(1)})
4039-
self.assertEqual(obj.serialize(), {b"data": {b"x": {b"type": b"Int", b"value": 1}}, b"type": b"Record"})
4038+
self.assertEqual(obj.serialize(), {"data": {"x": {"type": "Int", "value": 1}}, "type": "Record"})
40404039

40414040
def test_serialize_env_object(self) -> None:
40424041
obj = EnvObject({"x": Int(1)})
40434042
self.assertEqual(
40444043
obj.serialize(),
4045-
{b"env": {b"x": {b"type": b"Int", b"value": 1}}, b"type": b"EnvObject"},
4044+
{"env": {"x": {"type": "Int", "value": 1}}, "type": "EnvObject"},
40464045
)
40474046

40484047
def test_serialize_function(self) -> None:
40494048
obj = Function(Var("x"), Var("x"))
40504049
self.assertEqual(
40514050
obj.serialize(),
40524051
{
4053-
b"arg": {b"name": b"x", b"type": b"Var"},
4054-
b"body": {b"name": b"x", b"type": b"Var"},
4055-
b"type": b"Function",
4052+
"arg": {"name": "x", "type": "Var"},
4053+
"body": {"name": "x", "type": "Var"},
4054+
"type": "Function",
40564055
},
40574056
)
40584057

@@ -4061,9 +4060,9 @@ def test_serialize_apply(self) -> None:
40614060
self.assertEqual(
40624061
obj.serialize(),
40634062
{
4064-
b"func": {b"name": b"f", b"type": b"Var"},
4065-
b"arg": {b"name": b"x", b"type": b"Var"},
4066-
b"type": b"Apply",
4063+
"func": {"name": "f", "type": "Var"},
4064+
"arg": {"name": "x", "type": "Var"},
4065+
"type": "Apply",
40674066
},
40684067
)
40694068

@@ -4072,13 +4071,13 @@ def test_serialize_closure(self) -> None:
40724071
self.assertEqual(
40734072
obj.serialize(),
40744073
{
4075-
b"env": {b"a": {b"type": b"Int", b"value": 123}},
4076-
b"func": {
4077-
b"arg": {b"name": b"x", b"type": b"Var"},
4078-
b"body": {b"name": b"x", b"type": b"Var"},
4079-
b"type": b"Function",
4074+
"env": {"a": {"type": "Int", "value": 123}},
4075+
"func": {
4076+
"arg": {"name": "x", "type": "Var"},
4077+
"body": {"name": "x", "type": "Var"},
4078+
"type": "Function",
40804079
},
4081-
b"type": b"Closure",
4080+
"type": "Closure",
40824081
},
40834082
)
40844083

@@ -4181,7 +4180,7 @@ def test_serialize_str(self) -> None:
41814180

41824181
def test_serialize_bytes(self) -> None:
41834182
obj = Bytes(b"abc")
4184-
self.assertEqual(serialize(obj), b"d4:type5:Bytes5:value3:abce")
4183+
self.assertEqual(serialize(obj), b"d4:type5:Bytes5:value6:~~YWJje")
41854184

41864185
def test_serialize_var(self) -> None:
41874186
obj = Var("abc")

0 commit comments

Comments
 (0)