diff --git a/capnp/includes/capnp_cpp.pxd b/capnp/includes/capnp_cpp.pxd index c246d0b..7816d20 100644 --- a/capnp/includes/capnp_cpp.pxd +++ b/capnp/includes/capnp_cpp.pxd @@ -427,6 +427,7 @@ cdef extern from "capnp/dynamic.h" namespace " ::capnp": Reader(DynamicStruct.Reader& value) Reader(DynamicCapability.Client& value) Reader(PythonInterfaceDynamicImpl& value) + Reader(AnyPointer.Reader& value) Type getType() int64_t asInt"as"() uint64_t asUint"as"() diff --git a/capnp/lib/capnp.pyx b/capnp/lib/capnp.pyx index 2c8158a..eb6696a 100644 --- a/capnp/lib/capnp.pyx +++ b/capnp/lib/capnp.pyx @@ -661,6 +661,12 @@ cdef C_DynamicValue.Reader _extract_dynamic_server(object value): cdef C_DynamicValue.Reader _extract_dynamic_enum(_DynamicEnum value): return C_DynamicValue.Reader(value.thisptr) +cdef C_DynamicValue.Reader _extract_any_pointer(_DynamicObjectReader value): + return C_DynamicValue.Reader(value.thisptr) + +cdef C_DynamicValue.Reader _extract_any_pointer_builder(_DynamicObjectBuilder value): + return C_DynamicValue.Reader(value.thisptr.asReader()) + cdef _setBytes(_DynamicSetterClasses thisptr, field, value): cdef capnp.StringPtr temp_string = capnp.StringPtr(value, len(value)) cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(temp_string) @@ -726,6 +732,10 @@ cdef _setDynamicField(_DynamicSetterClasses thisptr, field, value, parent): thisptr.set(field, _extract_dynamic_server(value)) elif value_type is _DynamicEnum: thisptr.set(field, _extract_dynamic_enum(value)) + elif value_type is _DynamicObjectReader: + thisptr.set(field, _extract_any_pointer(value)) + elif value_type is _DynamicObjectBuilder: + thisptr.set(field, _extract_any_pointer_builder(value)) else: raise KjException("Tried to set field: '{}' with a value of: '{}' which is an unsupported type: '{}'".format(field, str(value), str(type(value)))) @@ -768,6 +778,10 @@ cdef _setDynamicFieldWithField(DynamicStruct_Builder thisptr, _StructSchemaField thisptr.setByField(field.thisptr, _extract_dynamic_server(value)) elif value_type is _DynamicEnum: thisptr.setByField(field.thisptr, _extract_dynamic_enum(value)) + elif value_type is _DynamicObjectReader: + thisptr.set(field, _extract_any_pointer(value)) + elif value_type is _DynamicObjectBuilder: + thisptr.set(field, _extract_any_pointer_builder(value)) else: raise KjException("Tried to set field: '{}' with a value of: '{}' which is an unsupported type: '{}'".format(field, str(value), str(type(value)))) @@ -810,6 +824,10 @@ cdef _setDynamicFieldStatic(DynamicStruct_Builder thisptr, field, value, parent) thisptr.set(field, _extract_dynamic_server(value)) elif value_type is _DynamicEnum: thisptr.set(field, _extract_dynamic_enum(value)) + elif value_type is _DynamicObjectReader: + thisptr.set(field, _extract_any_pointer(value)) + elif value_type is _DynamicObjectBuilder: + thisptr.set(field, _extract_any_pointer_builder(value)) else: raise KjException("Tried to set field: '{}' with a value of: '{}' which is an unsupported type: '{}'".format(field, str(value), str(type(value)))) diff --git a/test/test_capability.capnp b/test/test_capability.capnp index 816fdf3..6770a3a 100644 --- a/test/test_capability.capnp +++ b/test/test_capability.capnp @@ -89,3 +89,7 @@ struct BarParams { a @0 :Text; b @1 :Int32; } + +interface TestGeneric(MyObject) { + foo @0 (a :MyObject) -> (b: Text); +} diff --git a/test/test_capability.py b/test/test_capability.py index 1667d7d..71114ac 100644 --- a/test/test_capability.py +++ b/test/test_capability.py @@ -370,3 +370,16 @@ def test_struct_args(): assert client.bar(a='test', b=1).wait().c == 'test1' with pytest.raises(capnp.KjException): assert client.bar('test', 1).wait().c == 'test1' + + +class TestGeneric(capability.TestGeneric.Server): + def foo(self, a, **kwargs): + return a.as_text() + 'test' + + +def test_generic(): + client = capability.TestGeneric._new_client(TestGeneric()) + + obj = capnp._MallocMessageBuilder().get_root_as_any() + obj.set_as_text("anypointer_") + assert client.foo(obj).wait().b == 'anypointer_test'