Skip to content

Commit

Permalink
Support _DynamicListReader in _setDynamicField
Browse files Browse the repository at this point in the history
See the test for an explanation.

Note that I'm not sure what the purpose of `_setDynamicFieldWithField` and
`_setDynamicFieldStatic` is. It does not appear to be used. I've kept them for
now (they are a public API), but perhaps this can be removed.
  • Loading branch information
LasseBlaauwbroek authored and haata committed Nov 8, 2023
1 parent aafec22 commit ef5e039
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 0 deletions.
1 change: 1 addition & 0 deletions capnp/includes/capnp_cpp.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ cdef extern from "capnp/dynamic.h" namespace " ::capnp":
void adopt(uint, DynamicOrphan) except +reraise_kj_exception
DynamicOrphan disown(uint)
StructSchema getStructElementType'getSchema().getStructElementType'()
DynamicList.Reader asReader() except +reraise_kj_exception

cdef extern from "capnp/any.h" namespace " ::capnp":
cdef cppclass AnyPointer nogil:
Expand Down
22 changes: 22 additions & 0 deletions capnp/lib/capnp.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -714,6 +714,14 @@ cdef C_DynamicValue.Reader _extract_dynamic_struct_reader(_DynamicStructReader v
return C_DynamicValue.Reader(value.thisptr)


cdef C_DynamicValue.Reader _extract_dynamic_list_builder(_DynamicListBuilder value):
return C_DynamicValue.Reader(value.thisptr.asReader())


cdef C_DynamicValue.Reader _extract_dynamic_list_reader(_DynamicListReader value):
return C_DynamicValue.Reader(value.thisptr)


cdef C_DynamicValue.Reader _extract_dynamic_client(_DynamicCapabilityClient value):
return C_DynamicValue.Reader(value.thisptr)

Expand Down Expand Up @@ -805,6 +813,10 @@ cdef _setDynamicField(_DynamicSetterClasses thisptr, field, value, parent):
thisptr.set(field, _extract_dynamic_struct_builder(value))
elif value_type is _DynamicStructReader:
thisptr.set(field, _extract_dynamic_struct_reader(value))
elif value_type is _DynamicListBuilder:
thisptr.set(field, _extract_dynamic_list_builder(value))
elif value_type is _DynamicListReader:
thisptr.set(field, _extract_dynamic_list_reader(value))
elif value_type is _DynamicCapabilityClient:
thisptr.set(field, _extract_dynamic_client(value))
elif isinstance(value, _DynamicCapabilityServer):
Expand All @@ -821,6 +833,7 @@ cdef _setDynamicField(_DynamicSetterClasses thisptr, field, value, parent):
.format(field, str(value), str(type(value))))


# TODO: Is this function used by anyone? Can it be removed?
cdef _setDynamicFieldWithField(DynamicStruct_Builder thisptr, _StructSchemaField field, value, parent):
cdef C_DynamicValue.Reader temp
value_type = type(value)
Expand Down Expand Up @@ -854,6 +867,10 @@ cdef _setDynamicFieldWithField(DynamicStruct_Builder thisptr, _StructSchemaField
thisptr.setByField(field.thisptr, _extract_dynamic_struct_builder(value))
elif value_type is _DynamicStructReader:
thisptr.setByField(field.thisptr, _extract_dynamic_struct_reader(value))
elif value_type is _DynamicListBuilder:
thisptr.setByField(field.thisptr, _extract_dynamic_list_builder(value))
elif value_type is _DynamicListReader:
thisptr.setByField(field.thisptr, _extract_dynamic_list_reader(value))
elif value_type is _DynamicCapabilityClient:
thisptr.setByField(field.thisptr, _extract_dynamic_client(value))
elif isinstance(value, _DynamicCapabilityServer):
Expand All @@ -870,6 +887,7 @@ cdef _setDynamicFieldWithField(DynamicStruct_Builder thisptr, _StructSchemaField
.format(field, str(value), str(type(value))))


# TODO: Is this function used by anyone? Can it be removed?
cdef _setDynamicFieldStatic(DynamicStruct_Builder thisptr, field, value, parent):
cdef C_DynamicValue.Reader temp
value_type = type(value)
Expand Down Expand Up @@ -903,6 +921,10 @@ cdef _setDynamicFieldStatic(DynamicStruct_Builder thisptr, field, value, parent)
thisptr.set(field, _extract_dynamic_struct_builder(value))
elif value_type is _DynamicStructReader:
thisptr.set(field, _extract_dynamic_struct_reader(value))
elif value_type is _DynamicListBuilder:
thisptr.set(field, _extract_dynamic_list_builder(value))
elif value_type is _DynamicListReader:
thisptr.set(field, _extract_dynamic_list_reader(value))
elif value_type is _DynamicCapabilityClient:
thisptr.set(field, _extract_dynamic_client(value))
elif isinstance(value, _DynamicCapabilityServer):
Expand Down
2 changes: 2 additions & 0 deletions test/test_capability.capnp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ interface TestInterface {
bar @1 () -> ();
buz @2 (i: TestSturdyRefHostId) -> (x: Text);
bam @3 (i :UInt32, j :Bool) -> (x: Text, i:UInt32);
bak1 @4 () -> (i:List(UInt32));
bak2 @5 (i:List(UInt32)) -> ();
# baz @2 (s: TestAllTypes);
}

Expand Down
12 changes: 12 additions & 0 deletions test/test_capability.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ async def buz(self, i, **kwargs):
async def bam(self, i, **kwargs):
return str(i) + "_test", i

async def bak1(self, **kwargs):
return [1, 2, 3, 4, 5]

async def bak2(self, i, **kwargs):
assert i[4] == 5


class PipelineServer(capability.TestPipeline.Server):
async def getCap(self, n, inCap, _context, **kwargs):
Expand Down Expand Up @@ -67,6 +73,12 @@ async def test_client():
with pytest.raises(AttributeError):
req.baz = 1

resp = await client.bak1()
# Used to fail with
# capnp.lib.capnp.KjException: Tried to set field: 'i' with a value of: '[1, 2, 3, 4, 5]'
# which is an unsupported type: '<class 'capnp.lib.capnp._DynamicListReader'>'
await client.bak2(resp.i)


async def test_simple_client():
client = capability.TestInterface._new_client(Server())
Expand Down

0 comments on commit ef5e039

Please sign in to comment.