Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement _fields and _asdict() for struct. #33

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions capnpy/compiler/struct_.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ def emit_definition(self, m):
__static_ptrs_size__ = {ptrs_size}

""")
self._emit_fields(m, ns)
for child in m.children[self.id]:
child.emit_reference_as_child(m)
m.w()
Expand Down Expand Up @@ -97,6 +98,12 @@ def _get_enum_items(self, m):
enum_items[field.discriminantValue] = m._field_name(field)
return enum_items

def _emit_fields(self, m, ns):
fnames = []
for f in self.struct.fields or []:
fnames.append(m._field_name(f))
ns.w("_fields = {}".format(tuple(fnames)))

def _emit_union_tag_declaration(self, m):
enum_items = self._get_enum_items(m)
if not enum_items:
Expand Down
10 changes: 10 additions & 0 deletions capnpy/struct_.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from collections import OrderedDict

import capnpy
from capnpy import ptr
from capnpy.type import Types
Expand Down Expand Up @@ -44,6 +46,8 @@ class Struct(Blob):
__static_data_size__ = None
__static_ptrs_size__ = None

_fields = None

def __init__(self, buf, offset, data_size, ptrs_size):
self._init_from_buffer(buf, offset, data_size, ptrs_size)

Expand All @@ -69,6 +73,12 @@ def __reduce__(self):
self._data_size, self._ptrs_size)
return (struct_from_buffer, args)

def _asdict(self):
o = OrderedDict()
for f in self._fields:
o[f] = getattr(self, f)
return o

@classmethod
def from_buffer(cls, buf, offset, data_size, ptrs_size):
return struct_from_buffer(cls, buf, offset, data_size, ptrs_size)
Expand Down
29 changes: 29 additions & 0 deletions capnpy/testing/compiler/test_todict.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from capnpy.testing.compiler.support import CompilerTest


class TestTodict(CompilerTest):
def test_fields(self):
schema = """
@0xbf5147cbbecf40c1;
struct Point {
x @0 :Int64;
y @1 :Int64;
}
"""
mod = self.compile(schema)
assert mod.Point._fields == ('x', 'y')

def test_todict(self):
schema = """
@0xbf5147cbbecf40c1;
struct Point {
x @0 :Int64;
y @1 :Int64;
}
"""
mod = self.compile(schema)
p = mod.Point(1, 2)
d = p._asdict()
assert d == {'x': 1, 'y': 2}
assert list(d)[0] == 'x'

3 changes: 3 additions & 0 deletions docs/source/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,9 @@ inspired by ``namedtuples``:
value of a field, you can instantiate a new object, as you would do with
namedtuples

- ``_fields`` and ``_asdict()`` are provided with the same semantics as
namedtuple

- objects can be made `comparable and hashable`__ by specifying the
``$Py.key`` annotation

Expand Down