From 4f706c8b052c272c3ca185ead60b315c93b36f5c Mon Sep 17 00:00:00 2001 From: jfgauvin Date: Mon, 27 Oct 2014 10:59:07 -0400 Subject: [PATCH] Support ordered dictionnary Now possible to create ordered dictionnary using 'to_dict' function with the ordered parameter. --- capnp/lib/capnp.pxd | 2 +- capnp/lib/capnp.pyx | 45 ++++++++++++++++++++++---------------- capnp/templates/module.pyx | 8 +++---- 3 files changed, 31 insertions(+), 24 deletions(-) diff --git a/capnp/lib/capnp.pxd b/capnp/lib/capnp.pxd index 41827fd..3c4fdd7 100644 --- a/capnp/lib/capnp.pxd +++ b/capnp/lib/capnp.pxd @@ -117,7 +117,7 @@ cdef class _DynamicListBuilder: cdef to_python_reader(C_DynamicValue.Reader self, object parent) cdef to_python_builder(C_DynamicValue.Builder self, object parent) -cdef _to_dict(msg, bint verbose) +cdef _to_dict(msg, bint verbose, bint ordered) cdef _from_list(_DynamicListBuilder msg, list d) cdef _setDynamicFieldWithField(DynamicStruct_Builder thisptr, _StructSchemaField field, value, parent) cdef _setDynamicFieldStatic(DynamicStruct_Builder thisptr, field, value, parent) diff --git a/capnp/lib/capnp.pyx b/capnp/lib/capnp.pyx index 0b04ec2..d428214 100644 --- a/capnp/lib/capnp.pyx +++ b/capnp/lib/capnp.pyx @@ -28,6 +28,7 @@ from operator import attrgetter as _attrgetter import threading as _threading import socket as _socket import random as _random +import collections as _collections _CAPNP_VERSION_MAJOR = capnp.CAPNP_VERSION_MAJOR _CAPNP_VERSION_MINOR = capnp.CAPNP_VERSION_MINOR @@ -830,49 +831,55 @@ cdef _DynamicListReader temp_list_r cdef _DynamicResizableListBuilder temp_list_rb cdef _DynamicStructBuilder temp_msg_b cdef _DynamicStructReader temp_msg_r -cdef _to_dict(msg, bint verbose): +cdef _to_dict(msg, bint verbose, bint ordered): msg_type = type(msg) if msg_type is _DynamicListBuilder: temp_list_b = msg - return [_to_dict(temp_list_b._get(i), verbose) for i in range(len(msg))] + return [_to_dict(temp_list_b._get(i), verbose, ordered) for i in range(len(msg))] elif msg_type is _DynamicListReader: temp_list_r = msg - return [_to_dict(temp_list_r._get(i), verbose) for i in range(len(msg))] + return [_to_dict(temp_list_r._get(i), verbose, ordered) for i in range(len(msg))] elif msg_type is _DynamicResizableListBuilder: temp_list_rb = msg - return [_to_dict(temp_list_rb._get(i), verbose) for i in range(len(msg))] + return [_to_dict(temp_list_rb._get(i), verbose, ordered) for i in range(len(msg))] if msg_type is _DynamicStructBuilder: temp_msg_b = msg - ret = {} + if ordered: + ret = _collections.OrderedDict() + else: + ret = {} try: which = temp_msg_b.which() - ret[which] = _to_dict(temp_msg_b._get(which), verbose) + ret[which] = _to_dict(temp_msg_b._get(which), verbose, ordered) except ValueError: pass for field in temp_msg_b.schema.non_union_fields: if verbose or temp_msg_b._has(field): - ret[field] = _to_dict(temp_msg_b._get(field), verbose) + ret[field] = _to_dict(temp_msg_b._get(field), verbose, ordered) return ret elif msg_type is _DynamicStructReader: temp_msg_r = msg - ret = {} + if ordered: + ret = _collections.OrderedDict() + else: + ret = {} try: which = temp_msg_r.which() - ret[which] = _to_dict(temp_msg_r._get(which), verbose) + ret[which] = _to_dict(temp_msg_r._get(which), verbose, ordered) except ValueError: pass for field in temp_msg_r.schema.non_union_fields: if verbose or temp_msg_r._has(field): - ret[field] = _to_dict(temp_msg_r._get(field), verbose) + ret[field] = _to_dict(temp_msg_r._get(field), verbose, ordered) return ret if isinstance(msg, (_DynamicStructBuilder, _DynamicStructReader)): - return msg.to_dict() + return msg.to_dict(verbose, ordered) if msg_type is _DynamicEnum: return str(msg) @@ -1063,8 +1070,8 @@ cdef class _DynamicStructReader: def __repr__(self): return '<%s reader %s>' % (self.schema.node.displayName, strStructReader(self.thisptr).cStr()) - def to_dict(self, verbose=False): - return _to_dict(self, verbose) + def to_dict(self, verbose=False, ordered=False): + return _to_dict(self, verbose, ordered) cpdef as_builder(self, num_first_segment_words=None): """A method for casting this Builder to a Reader @@ -1375,8 +1382,8 @@ cdef class _DynamicStructBuilder: def __repr__(self): return '<%s builder %s>' % (self.schema.node.displayName, strStructBuilder(self.thisptr).cStr()) - def to_dict(self, verbose=False): - return _to_dict(self, verbose) + def to_dict(self, verbose=False, ordered=False): + return _to_dict(self, verbose, ordered) def from_dict(self, dict d): for key, val in d.iteritems(): @@ -1442,8 +1449,8 @@ cdef class _DynamicStructPipeline: # def __repr__(self): # return '<%s reader %s>' % (self.schema.node.displayName, strStructReader(self.thisptr).cStr()) - def to_dict(self, verbose=False): - return _to_dict(self, verbose) + def to_dict(self, verbose=False, ordered=False): + return _to_dict(self, verbose, ordered) cdef class _DynamicOrphan: cdef _init(self, C_DynamicOrphan other, object parent): @@ -1860,8 +1867,8 @@ cdef class _RemotePromise: def __dir__(self): return list(self.schema.fieldnames) - def to_dict(self, verbose=False): - return _to_dict(self, verbose) + def to_dict(self, verbose=False, ordered=False): + return _to_dict(self, verbose, ordered) cpdef cancel(self, numParents=1) except +reraise_kj_exception: if numParents > 0 and hasattr(self._parent, 'cancel'): diff --git a/capnp/templates/module.pyx b/capnp/templates/module.pyx index 0bf3927..9d959cd 100644 --- a/capnp/templates/module.pyx +++ b/capnp/templates/module.pyx @@ -214,11 +214,11 @@ cdef class {{node.module_name}}_Reader(_DynamicStructReader): return self._get_{{field.name}}() {%- endfor %} - def to_dict(self, verbose=False): + def to_dict(self, verbose=False, ordered=False): ret = { {% for field in node.struct.fields %} {% if field.discriminantValue == 65535 %} - '{{field.name}}': _to_dict(self.{{field.name}}, verbose), + '{{field.name}}': _to_dict(self.{{field.name}}, verbose, ordered), {% endif %} {%- endfor %} } @@ -246,11 +246,11 @@ cdef class {{node.module_name}}_Builder(_DynamicStructBuilder): self._set_{{field.name}}(value) {%- endfor %} - def to_dict(self, verbose=False): + def to_dict(self, verbose=False, ordered=False): ret = { {% for field in node.struct.fields %} {% if field.discriminantValue == 65535 %} - '{{field.name}}': _to_dict(self.{{field.name}}, verbose), + '{{field.name}}': _to_dict(self.{{field.name}}, verbose, ordered), {% endif %} {%- endfor %} }