Author: Ronan Lamy <ronan.l...@gmail.com> Branch: singledispatch Changeset: r69171:be668feb3655 Date: 2014-02-16 03:23 +0000 http://bitbucket.org/pypy/pypy/changeset/be668feb3655/
Log: use singledispatch in rlib.rmarshal diff --git a/rpython/rlib/rmarshal.py b/rpython/rlib/rmarshal.py --- a/rpython/rlib/rmarshal.py +++ b/rpython/rlib/rmarshal.py @@ -1,11 +1,11 @@ """A way to serialize data in the same format as the 'marshal' module but accessible to RPython programs. """ +from rpython.tool.singledispatch.singledispatch import singledispatch from rpython.annotator import model as annmodel from rpython.annotator.signature import annotation from rpython.annotator.listdef import ListDef, TooLateForChange -from rpython.tool.pairtype import pair, pairtype from rpython.rlib.rarithmetic import r_longlong, intmask, LONG_BIT, ovfcheck from rpython.rlib.rfloat import formatd, rstring_to_float from rpython.rlib.unroll import unrolling_iterable @@ -29,7 +29,7 @@ return find_dumper(s_obj) except CannotMarshal: # ask the annotation to produce an appropriate dumper - pair(_tag, s_obj).install_marshaller() + install_marshaller(s_obj) return find_dumper(s_obj) get_marshaller._annspecialcase_ = 'specialize:memo' @@ -40,7 +40,7 @@ return find_loader(s_obj) except CannotUnmarshall: # ask the annotation to produce an appropriate loader - pair(_tag, s_obj).install_unmarshaller() + install_unmarshaller(s_obj) return find_loader(s_obj) def get_unmarshaller(type): @@ -325,11 +325,6 @@ # # Annotations => dumpers and loaders -class MTag(object): - """Tag for pairtype(), for the purpose of making the get_marshaller() - and get_unmarshaller() methods of SomeObject only locally visible.""" -_tag = MTag() - def weakly_contains(s_bigger, s_smaller): # a special version of s_bigger.contains(s_smaller). Warning, to # support ListDefs properly, this works by trying to produce a side-effect @@ -342,145 +337,156 @@ except (annmodel.UnionError, TooLateForChange): return False +@singledispatch +def install_marshaller(obj): + raise NotImplementedError -class __extend__(pairtype(MTag, annmodel.SomeObject)): - def install_marshaller((tag, s_obj)): - if not hasattr(s_obj, '_get_rmarshall_support_'): - raise CannotMarshal(s_obj) - # special support for custom annotation like SomeStatResult: - # the annotation tells us how to turn an object into something - # else that can be marshalled - def dump_with_custom_reduce(buf, x): - reduced_obj = fn_reduce(x) - reduceddumper(buf, reduced_obj) - s_reduced_obj, fn_reduce, fn_recreate = s_obj._get_rmarshall_support_() - reduceddumper = get_marshaller(s_reduced_obj) - add_dumper(s_obj, dump_with_custom_reduce) +@singledispatch +def install_unmarshaller(obj): + raise NotImplementedError - def install_unmarshaller((tag, s_obj)): - if not hasattr(s_obj, '_get_rmarshall_support_'): - raise CannotUnmarshall(s_obj) - # special support for custom annotation like SomeStatResult - def load_with_custom_recreate(loader): - reduced_obj = reducedloader(loader) - return fn_recreate(reduced_obj) - s_reduced_obj, fn_reduce, fn_recreate = s_obj._get_rmarshall_support_() - reducedloader = get_loader(s_reduced_obj) - add_loader(s_obj, load_with_custom_recreate) +@install_marshaller.register(annmodel.SomeObject) +def _(s_obj): + if not hasattr(s_obj, '_get_rmarshall_support_'): + raise CannotMarshal(s_obj) -class __extend__(pairtype(MTag, annmodel.SomeList)): + # special support for custom annotation like SomeStatResult: + # the annotation tells us how to turn an object into something + # else that can be marshalled + def dump_with_custom_reduce(buf, x): + reduced_obj = fn_reduce(x) + reduceddumper(buf, reduced_obj) + s_reduced_obj, fn_reduce, fn_recreate = s_obj._get_rmarshall_support_() + reduceddumper = get_marshaller(s_reduced_obj) + add_dumper(s_obj, dump_with_custom_reduce) - def install_marshaller((tag, s_list)): - def dump_list_or_none(buf, x): - if x is None: - dump_none(buf, x) - else: - buf.append(TYPE_LIST) - w_long(buf, len(x)) - for item in x: - itemdumper(buf, item) +@install_unmarshaller.register(annmodel.SomeObject) +def _(s_obj): + if not hasattr(s_obj, '_get_rmarshall_support_'): + raise CannotUnmarshall(s_obj) - itemdumper = get_marshaller(s_list.listdef.listitem.s_value) - if s_list.listdef.listitem.dont_change_any_more: - s_general_list = s_list + # special support for custom annotation like SomeStatResult + def load_with_custom_recreate(loader): + reduced_obj = reducedloader(loader) + return fn_recreate(reduced_obj) + s_reduced_obj, fn_reduce, fn_recreate = s_obj._get_rmarshall_support_() + reducedloader = get_loader(s_reduced_obj) + add_loader(s_obj, load_with_custom_recreate) + + +@install_marshaller.register(annmodel.SomeList) +def _(s_list): + def dump_list_or_none(buf, x): + if x is None: + dump_none(buf, x) else: - s_item = get_dumper_annotation(itemdumper) - s_general_list = annotation([s_item]) - add_dumper(s_general_list, dump_list_or_none) + buf.append(TYPE_LIST) + w_long(buf, len(x)) + for item in x: + itemdumper(buf, item) - def install_unmarshaller((tag, s_list)): - def load_list_or_none(loader): - t = readchr(loader) - if t == TYPE_LIST: - length = readlong(loader) - result = [] - for i in range(length): - result.append(itemloader(loader)) - return result - elif t == TYPE_NONE: - return None - else: - raise ValueError("expected a list or None") + itemdumper = get_marshaller(s_list.listdef.listitem.s_value) + if s_list.listdef.listitem.dont_change_any_more: + s_general_list = s_list + else: + s_item = get_dumper_annotation(itemdumper) + s_general_list = annotation([s_item]) + add_dumper(s_general_list, dump_list_or_none) - itemloader = get_loader(s_list.listdef.listitem.s_value) - add_loader(s_list, load_list_or_none) +@install_unmarshaller.register(annmodel.SomeList) +def _(s_list): + def load_list_or_none(loader): + t = readchr(loader) + if t == TYPE_LIST: + length = readlong(loader) + result = [] + for i in range(length): + result.append(itemloader(loader)) + return result + elif t == TYPE_NONE: + return None + else: + raise ValueError("expected a list or None") + itemloader = get_loader(s_list.listdef.listitem.s_value) + 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 +@install_marshaller.register(annmodel.SomeDict) +def _(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 + 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 + 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) + +@install_unmarshaller.register(annmodel.SomeDict) +def _(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: - 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) + raise ValueError("expected a 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) - 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) +@install_marshaller.register(annmodel.SomeTuple) +def _(s_tuple): + def dump_tuple(buf, x): + buf.append(TYPE_TUPLE) + w_long(buf, len(x)) + for i, itemdumper in unroll_item_dumpers: + itemdumper(buf, x[i]) -class __extend__(pairtype(MTag, annmodel.SomeTuple)): + itemdumpers = [get_marshaller(s_item) for s_item in s_tuple.items] + unroll_item_dumpers = unrolling_iterable(enumerate(itemdumpers)) + dumper_annotations = [get_dumper_annotation(itemdumper) + for itemdumper in itemdumpers] + s_general_tuple = annmodel.SomeTuple(dumper_annotations) + add_dumper(s_general_tuple, dump_tuple) - def install_marshaller((tag, s_tuple)): - def dump_tuple(buf, x): - buf.append(TYPE_TUPLE) - w_long(buf, len(x)) - for i, itemdumper in unroll_item_dumpers: - itemdumper(buf, x[i]) +@install_unmarshaller.register(annmodel.SomeTuple) +def _(s_tuple): + def load_tuple(loader): + if readchr(loader) != TYPE_TUPLE: + raise ValueError("expected a tuple") + if readlong(loader) != expected_length: + raise ValueError("wrong tuple length") + result = () + for i, itemloader in unroll_item_loaders: + result += (itemloader(loader),) + return result - itemdumpers = [get_marshaller(s_item) for s_item in s_tuple.items] - unroll_item_dumpers = unrolling_iterable(enumerate(itemdumpers)) - dumper_annotations = [get_dumper_annotation(itemdumper) - for itemdumper in itemdumpers] - s_general_tuple = annmodel.SomeTuple(dumper_annotations) - add_dumper(s_general_tuple, dump_tuple) - - def install_unmarshaller((tag, s_tuple)): - def load_tuple(loader): - if readchr(loader) != TYPE_TUPLE: - raise ValueError("expected a tuple") - if readlong(loader) != expected_length: - raise ValueError("wrong tuple length") - result = () - for i, itemloader in unroll_item_loaders: - result += (itemloader(loader),) - return result - - itemloaders = [get_loader(s_item) for s_item in s_tuple.items] - expected_length = len(itemloaders) - unroll_item_loaders = unrolling_iterable(enumerate(itemloaders)) - add_loader(s_tuple, load_tuple) + itemloaders = [get_loader(s_item) for s_item in s_tuple.items] + expected_length = len(itemloaders) + unroll_item_loaders = unrolling_iterable(enumerate(itemloaders)) + add_loader(s_tuple, load_tuple) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit