Author: Armin Rigo <[email protected]>
Branch:
Changeset: r65964:c6a81f72894e
Date: 2013-08-06 12:24 +0200
http://bitbucket.org/pypy/pypy/changeset/c6a81f72894e/
Log: rmarshal: support dicts
diff --git a/rpython/rlib/rmarshal.py b/rpython/rlib/rmarshal.py
--- a/rpython/rlib/rmarshal.py
+++ b/rpython/rlib/rmarshal.py
@@ -77,6 +77,7 @@
TYPE_STRING = 's'
TYPE_TUPLE = '('
TYPE_LIST = '['
+TYPE_DICT = '{'
dumpers = []
loaders = []
@@ -302,6 +303,12 @@
loader.pos = pos + 1
return loader.buf[pos]
+def peekchr(loader):
+ pos = loader.pos
+ while pos >= len(loader.buf):
+ loader.need_more_data()
+ return loader.buf[pos]
+
def readlong(loader):
a = ord(readchr(loader))
b = ord(readchr(loader))
@@ -398,6 +405,51 @@
add_loader(s_list, load_list_or_none)
+class __extend__(pairtype(MTag, annmodel.SomeDict)):
+
+ def install_marshaller((tag, s_dict)):
+ def dump_dict_or_none(buf, x):
+ if x is None:
+ dump_none(buf, x)
+ else:
+ buf.append(TYPE_DICT)
+ for key, value in x.items():
+ keydumper(buf, key)
+ valuedumper(buf, value)
+ buf.append('0') # end of dict
+
+ keydumper = get_marshaller(s_dict.dictdef.dictkey.s_value)
+ valuedumper = get_marshaller(s_dict.dictdef.dictvalue.s_value)
+ if (s_dict.dictdef.dictkey.dont_change_any_more or
+ s_dict.dictdef.dictvalue.dont_change_any_more):
+ s_general_dict = s_dict
+ else:
+ s_key = get_dumper_annotation(keydumper)
+ s_value = get_dumper_annotation(valuedumper)
+ s_general_dict = annotation({s_key: s_value})
+ add_dumper(s_general_dict, dump_dict_or_none)
+
+ def install_unmarshaller((tag, s_dict)):
+ def load_dict_or_none(loader):
+ t = readchr(loader)
+ if t == TYPE_DICT:
+ result = {}
+ while peekchr(loader) != '0':
+ key = keyloader(loader)
+ value = valueloader(loader)
+ result[key] = value
+ readchr(loader) # consume the final '0'
+ return result
+ elif t == TYPE_NONE:
+ return None
+ else:
+ raise ValueError("expected a dict or None")
+
+ keyloader = get_loader(s_dict.dictdef.dictkey.s_value)
+ valueloader = get_loader(s_dict.dictdef.dictvalue.s_value)
+ add_loader(s_dict, load_dict_or_none)
+
+
class __extend__(pairtype(MTag, annmodel.SomeTuple)):
def install_marshaller((tag, s_tuple)):
diff --git a/rpython/rlib/test/test_rmarshal.py
b/rpython/rlib/test/test_rmarshal.py
--- a/rpython/rlib/test/test_rmarshal.py
+++ b/rpython/rlib/test/test_rmarshal.py
@@ -9,6 +9,7 @@
[int],
annmodel.SomeString(can_be_None=True),
annmodel.s_None,
+ {int: int},
]
@@ -58,6 +59,10 @@
get_marshaller((int, float, (str, ())))(buf, (7, -1.5, ("foo", ())))
assert marshal.loads(''.join(buf)) == (7, -1.5, ("foo", ()))
+ buf = []
+ get_marshaller({int: str})(buf, {2: "foo", -3: "bar"})
+ assert marshal.loads(''.join(buf)) == {2: "foo", -3: "bar"}
+
for typ in types_that_can_be_none:
buf = []
get_marshaller(typ)(buf, None)
@@ -111,6 +116,11 @@
res = get_unmarshaller((int, (str, ())))(buf)
assert res == (7, ("foo", ()))
+ buf = ('{i\xfb\xff\xff\xffs\x03\x00\x00\x00bar'
+ 'i\x06\x00\x00\x00s\x00\x00\x00\x000')
+ res = get_unmarshaller({int: str})(buf)
+ assert res == {-5: "bar", 6: ""}
+
for typ in types_that_can_be_none:
buf = 'N'
assert get_unmarshaller(typ)(buf) is None
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit