Allow setting of fields with python dicts.
This change was a bit complicated because of a bug in cython fused types. I had to flatten DynamicStruct.Builder to DynamicStruct_Builder in order to get fused template specialization working.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
from .capnp.includes.capnp_cpp cimport Maybe, DynamicStruct, Request, PyPromise, VoidPromise, PyPromiseArray, RemotePromise, DynamicCapability, InterfaceSchema, EnumSchema, StructSchema, DynamicValue, Capability, RpcSystem, MessageBuilder, MessageReader, TwoPartyVatNetwork, PyRestorer, AnyPointer
|
from .capnp.includes.capnp_cpp cimport Maybe, DynamicStruct, Request, PyPromise, VoidPromise, PyPromiseArray, RemotePromise, DynamicCapability, InterfaceSchema, EnumSchema, StructSchema, DynamicValue, Capability, RpcSystem, MessageBuilder, MessageReader, TwoPartyVatNetwork, PyRestorer, AnyPointer, DynamicStruct_Builder
|
||||||
|
|
||||||
from non_circular cimport reraise_kj_exception
|
from non_circular cimport reraise_kj_exception
|
||||||
|
|
||||||
@@ -7,7 +7,7 @@ from cpython.ref cimport PyObject
|
|||||||
cdef extern from "../helpers/fixMaybe.h":
|
cdef extern from "../helpers/fixMaybe.h":
|
||||||
EnumSchema.Enumerant fixMaybe(Maybe[EnumSchema.Enumerant]) except +reraise_kj_exception
|
EnumSchema.Enumerant fixMaybe(Maybe[EnumSchema.Enumerant]) except +reraise_kj_exception
|
||||||
char * getEnumString(DynamicStruct.Reader val)
|
char * getEnumString(DynamicStruct.Reader val)
|
||||||
char * getEnumString(DynamicStruct.Builder val)
|
char * getEnumString(DynamicStruct_Builder val)
|
||||||
char * getEnumString(Request val)
|
char * getEnumString(Request val)
|
||||||
|
|
||||||
cdef extern from "../helpers/capabilityHelper.h":
|
cdef extern from "../helpers/capabilityHelper.h":
|
||||||
|
|||||||
@@ -205,24 +205,24 @@ cdef extern from "capnp/dynamic.h" namespace " ::capnp":
|
|||||||
bint has(char *) except +reraise_kj_exception
|
bint has(char *) except +reraise_kj_exception
|
||||||
StructSchema getSchema()
|
StructSchema getSchema()
|
||||||
Maybe[StructSchema.Field] which()
|
Maybe[StructSchema.Field] which()
|
||||||
cppclass Builder:
|
|
||||||
Builder()
|
|
||||||
Builder(Builder &)
|
|
||||||
DynamicValueForward.Builder get(char *) except +reraise_kj_exception
|
|
||||||
bint has(char *) except +reraise_kj_exception
|
|
||||||
void set(char *, DynamicValueForward.Reader) except +reraise_kj_exception
|
|
||||||
DynamicValueForward.Builder init(char *, uint size) except +reraise_kj_exception
|
|
||||||
DynamicValueForward.Builder init(char *) except +reraise_kj_exception
|
|
||||||
StructSchema getSchema()
|
|
||||||
Maybe[StructSchema.Field] which()
|
|
||||||
void adopt(char *, DynamicOrphan) except +reraise_kj_exception
|
|
||||||
DynamicOrphan disown(char *)
|
|
||||||
DynamicStruct.Reader asReader()
|
|
||||||
cppclass Pipeline:
|
cppclass Pipeline:
|
||||||
Pipeline()
|
Pipeline()
|
||||||
Pipeline(Pipeline &)
|
Pipeline(Pipeline &)
|
||||||
DynamicValueForward.Pipeline get(char *)
|
DynamicValueForward.Pipeline get(char *)
|
||||||
StructSchema getSchema()
|
StructSchema getSchema()
|
||||||
|
cdef cppclass DynamicStruct_Builder" ::capnp::DynamicStruct::Builder": # Need to flatten this class out, since nested C++ classes cause havoc with cython fused types
|
||||||
|
DynamicStruct_Builder()
|
||||||
|
DynamicStruct_Builder(DynamicStruct_Builder &)
|
||||||
|
DynamicValueForward.Builder get(char *) except +reraise_kj_exception
|
||||||
|
bint has(char *) except +reraise_kj_exception
|
||||||
|
void set(char *, DynamicValueForward.Reader) except +reraise_kj_exception
|
||||||
|
DynamicValueForward.Builder init(char *, uint size) except +reraise_kj_exception
|
||||||
|
DynamicValueForward.Builder init(char *) except +reraise_kj_exception
|
||||||
|
StructSchema getSchema()
|
||||||
|
Maybe[StructSchema.Field] which()
|
||||||
|
void adopt(char *, DynamicOrphan) except +reraise_kj_exception
|
||||||
|
DynamicOrphan disown(char *)
|
||||||
|
DynamicStruct.Reader asReader()
|
||||||
|
|
||||||
cdef extern from "capnp/dynamic.h" namespace " ::capnp":
|
cdef extern from "capnp/dynamic.h" namespace " ::capnp":
|
||||||
cdef cppclass DynamicCapability:
|
cdef cppclass DynamicCapability:
|
||||||
@@ -282,7 +282,7 @@ cdef extern from "capnp/any.h" namespace " ::capnp":
|
|||||||
StringPtr getAsText"getAs< ::capnp::Text>"()
|
StringPtr getAsText"getAs< ::capnp::Text>"()
|
||||||
cppclass Builder:
|
cppclass Builder:
|
||||||
Builder(Builder)
|
Builder(Builder)
|
||||||
DynamicStruct.Builder getAs"getAs< ::capnp::DynamicStruct>"(StructSchema)
|
DynamicStruct_Builder getAs"getAs< ::capnp::DynamicStruct>"(StructSchema)
|
||||||
StringPtr getAsText"getAs< ::capnp::Text>"()
|
StringPtr getAsText"getAs< ::capnp::Text>"()
|
||||||
void setAsStruct"setAs< ::capnp::DynamicStruct>"(DynamicStruct.Reader&) except +reraise_kj_exception
|
void setAsStruct"setAs< ::capnp::DynamicStruct>"(DynamicStruct.Reader&) except +reraise_kj_exception
|
||||||
void setAsText"setAs< ::capnp::Text>"(char*) except +reraise_kj_exception
|
void setAsText"setAs< ::capnp::Text>"(char*) except +reraise_kj_exception
|
||||||
@@ -359,7 +359,7 @@ cdef extern from "capnp/dynamic.h" namespace " ::capnp":
|
|||||||
double asDouble"as<double>"()
|
double asDouble"as<double>"()
|
||||||
StringPtr asText"as< ::capnp::Text>"()
|
StringPtr asText"as< ::capnp::Text>"()
|
||||||
DynamicList.Builder asList"as< ::capnp::DynamicList>"()
|
DynamicList.Builder asList"as< ::capnp::DynamicList>"()
|
||||||
DynamicStruct.Builder asStruct"as< ::capnp::DynamicStruct>"()
|
DynamicStruct_Builder asStruct"as< ::capnp::DynamicStruct>"()
|
||||||
AnyPointer.Builder asObject"as< ::capnp::AnyPointer>"()
|
AnyPointer.Builder asObject"as< ::capnp::AnyPointer>"()
|
||||||
DynamicCapability.Client asCapability"as< ::capnp::DynamicCapability>"()
|
DynamicCapability.Client asCapability"as< ::capnp::DynamicCapability>"()
|
||||||
DynamicEnum asEnum"as< ::capnp::DynamicEnum>"()
|
DynamicEnum asEnum"as< ::capnp::DynamicEnum>"()
|
||||||
@@ -389,8 +389,8 @@ cdef extern from "capnp/capability.h" namespace " ::capnp":
|
|||||||
DynamicStruct.Reader getParams() except +reraise_kj_exception
|
DynamicStruct.Reader getParams() except +reraise_kj_exception
|
||||||
void releaseParams() except +reraise_kj_exception
|
void releaseParams() except +reraise_kj_exception
|
||||||
|
|
||||||
DynamicStruct.Builder getResults()
|
DynamicStruct_Builder getResults()
|
||||||
DynamicStruct.Builder initResults()
|
DynamicStruct_Builder initResults()
|
||||||
void setResults(DynamicStruct.Reader value)
|
void setResults(DynamicStruct.Reader value)
|
||||||
# void adoptResults(Orphan<Results>&& value);
|
# void adoptResults(Orphan<Results>&& value);
|
||||||
# Orphanage getResultsOrphanage(uint firstSegmentWordSize = 0);
|
# Orphanage getResultsOrphanage(uint firstSegmentWordSize = 0);
|
||||||
|
|||||||
@@ -18,8 +18,9 @@ cdef extern from "capnp/dynamic.h" namespace " ::capnp":
|
|||||||
cdef cppclass DynamicStruct:
|
cdef cppclass DynamicStruct:
|
||||||
cppclass Reader:
|
cppclass Reader:
|
||||||
pass
|
pass
|
||||||
cppclass Builder:
|
|
||||||
pass
|
cdef cppclass DynamicStruct_Builder" ::capnp::DynamicStruct::Builder":
|
||||||
|
pass
|
||||||
|
|
||||||
cdef extern from "capnp/schema.h" namespace " ::capnp":
|
cdef extern from "capnp/schema.h" namespace " ::capnp":
|
||||||
cdef cppclass Schema:
|
cdef cppclass Schema:
|
||||||
@@ -658,8 +659,8 @@ cdef extern from "capnp/message.h" namespace " ::capnp":
|
|||||||
Annotation.Builder getRootAnnotation'getRoot< ::capnp::schema::Annotation>'()
|
Annotation.Builder getRootAnnotation'getRoot< ::capnp::schema::Annotation>'()
|
||||||
Annotation.Builder initRootAnnotation'initRoot< ::capnp::schema::Annotation>'()
|
Annotation.Builder initRootAnnotation'initRoot< ::capnp::schema::Annotation>'()
|
||||||
|
|
||||||
DynamicStruct.Builder getRootDynamicStruct'getRoot< ::capnp::DynamicStruct>'(StructSchema)
|
DynamicStruct_Builder getRootDynamicStruct'getRoot< ::capnp::DynamicStruct>'(StructSchema)
|
||||||
DynamicStruct.Builder initRootDynamicStruct'initRoot< ::capnp::DynamicStruct>'(StructSchema)
|
DynamicStruct_Builder initRootDynamicStruct'initRoot< ::capnp::DynamicStruct>'(StructSchema)
|
||||||
void setRootDynamicStruct'setRoot< ::capnp::DynamicStruct::Reader>'(DynamicStruct.Reader)
|
void setRootDynamicStruct'setRoot< ::capnp::DynamicStruct::Reader>'(DynamicStruct.Reader)
|
||||||
|
|
||||||
AnyPointer.Builder getRootAnyPointer'getRoot< ::capnp::AnyPointer>'()
|
AnyPointer.Builder getRootAnyPointer'getRoot< ::capnp::AnyPointer>'()
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from .capnp.includes cimport capnp_cpp as capnp
|
from .capnp.includes cimport capnp_cpp as capnp
|
||||||
from .capnp.includes cimport schema_cpp
|
from .capnp.includes cimport schema_cpp
|
||||||
from .capnp.includes.capnp_cpp cimport Schema as C_Schema, StructSchema as C_StructSchema, InterfaceSchema as C_InterfaceSchema, DynamicStruct as C_DynamicStruct, DynamicValue as C_DynamicValue, Type as C_Type, DynamicList as C_DynamicList, SchemaParser as C_SchemaParser, ParsedSchema as C_ParsedSchema, VOID, ArrayPtr, StringPtr, String, StringTree, DynamicOrphan as C_DynamicOrphan, AnyPointer as C_DynamicObject, DynamicCapability as C_DynamicCapability, Request, Response, RemotePromise, PyPromise, VoidPromise, CallContext, PyRestorer, RpcSystem, makeRpcServer, makeRpcClient, Capability as C_Capability, TwoPartyVatNetwork as C_TwoPartyVatNetwork, Side, AsyncIoStream, Own, makeTwoPartyVatNetwork, PromiseFulfillerPair as C_PromiseFulfillerPair, copyPromiseFulfillerPair, newPromiseAndFulfiller, PyArray
|
from .capnp.includes.capnp_cpp cimport Schema as C_Schema, StructSchema as C_StructSchema, InterfaceSchema as C_InterfaceSchema, DynamicStruct as C_DynamicStruct, DynamicValue as C_DynamicValue, Type as C_Type, DynamicList as C_DynamicList, SchemaParser as C_SchemaParser, ParsedSchema as C_ParsedSchema, VOID, ArrayPtr, StringPtr, String, StringTree, DynamicOrphan as C_DynamicOrphan, AnyPointer as C_DynamicObject, DynamicCapability as C_DynamicCapability, Request, Response, RemotePromise, PyPromise, VoidPromise, CallContext, PyRestorer, RpcSystem, makeRpcServer, makeRpcClient, Capability as C_Capability, TwoPartyVatNetwork as C_TwoPartyVatNetwork, Side, AsyncIoStream, Own, makeTwoPartyVatNetwork, PromiseFulfillerPair as C_PromiseFulfillerPair, copyPromiseFulfillerPair, newPromiseAndFulfiller, PyArray, DynamicStruct_Builder
|
||||||
from .capnp.includes.schema_cpp cimport Node as C_Node, EnumNode as C_EnumNode
|
from .capnp.includes.schema_cpp cimport Node as C_Node, EnumNode as C_EnumNode
|
||||||
from .capnp.includes.types cimport *
|
from .capnp.includes.types cimport *
|
||||||
from .capnp.helpers.non_circular cimport reraise_kj_exception
|
from .capnp.helpers.non_circular cimport reraise_kj_exception
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ cdef public RemotePromise * extract_remote_promise(object obj):
|
|||||||
|
|
||||||
cdef extern from "<kj/string.h>" namespace " ::kj":
|
cdef extern from "<kj/string.h>" namespace " ::kj":
|
||||||
String strStructReader" ::kj::str"(C_DynamicStruct.Reader)
|
String strStructReader" ::kj::str"(C_DynamicStruct.Reader)
|
||||||
String strStructBuilder" ::kj::str"(C_DynamicStruct.Builder)
|
String strStructBuilder" ::kj::str"(DynamicStruct_Builder)
|
||||||
String strRequest" ::kj::str"(Request &)
|
String strRequest" ::kj::str"(Request &)
|
||||||
String strListReader" ::kj::str"(C_DynamicList.Reader)
|
String strListReader" ::kj::str"(C_DynamicList.Reader)
|
||||||
String strListBuilder" ::kj::str"(C_DynamicList.Builder)
|
String strListBuilder" ::kj::str"(C_DynamicList.Builder)
|
||||||
@@ -269,7 +269,7 @@ ctypedef fused _DynamicStructReaderOrBuilder:
|
|||||||
|
|
||||||
ctypedef fused _DynamicSetterClasses:
|
ctypedef fused _DynamicSetterClasses:
|
||||||
C_DynamicList.Builder
|
C_DynamicList.Builder
|
||||||
C_DynamicStruct.Builder
|
DynamicStruct_Builder
|
||||||
Request
|
Request
|
||||||
|
|
||||||
ctypedef fused PromiseTypes:
|
ctypedef fused PromiseTypes:
|
||||||
@@ -307,7 +307,7 @@ cdef extern from "<utility>" namespace "std":
|
|||||||
|
|
||||||
cdef extern from "<capnp/pretty-print.h>" namespace " ::capnp":
|
cdef extern from "<capnp/pretty-print.h>" namespace " ::capnp":
|
||||||
StringTree printStructReader" ::capnp::prettyPrint"(C_DynamicStruct.Reader)
|
StringTree printStructReader" ::capnp::prettyPrint"(C_DynamicStruct.Reader)
|
||||||
StringTree printStructBuilder" ::capnp::prettyPrint"(C_DynamicStruct.Builder)
|
StringTree printStructBuilder" ::capnp::prettyPrint"(DynamicStruct_Builder)
|
||||||
StringTree printRequest" ::capnp::prettyPrint"(Request &)
|
StringTree printRequest" ::capnp::prettyPrint"(Request &)
|
||||||
StringTree printListReader" ::capnp::prettyPrint"(C_DynamicList.Reader)
|
StringTree printListReader" ::capnp::prettyPrint"(C_DynamicList.Reader)
|
||||||
StringTree printListBuilder" ::capnp::prettyPrint"(C_DynamicList.Builder)
|
StringTree printListBuilder" ::capnp::prettyPrint"(C_DynamicList.Builder)
|
||||||
@@ -673,6 +673,13 @@ cdef _setDynamicField(_DynamicSetterClasses thisptr, field, value, parent):
|
|||||||
builder = to_python_builder(thisptr.init(field, len(value)), parent)
|
builder = to_python_builder(thisptr.init(field, len(value)), parent)
|
||||||
for (i, v) in enumerate(value):
|
for (i, v) in enumerate(value):
|
||||||
builder[i] = v
|
builder[i] = v
|
||||||
|
elif value_type is dict:
|
||||||
|
if (_DynamicSetterClasses is DynamicStruct_Builder or _DynamicSetterClasses is Request):
|
||||||
|
builder = to_python_builder(thisptr.get(field), parent)
|
||||||
|
_from_dict(builder, value)
|
||||||
|
else:
|
||||||
|
builder = to_python_builder(thisptr[field], parent)
|
||||||
|
_from_dict(builder, value)
|
||||||
elif value is None:
|
elif value is None:
|
||||||
temp = C_DynamicValue.Reader(VOID)
|
temp = C_DynamicValue.Reader(VOID)
|
||||||
thisptr.set(field, temp)
|
thisptr.set(field, temp)
|
||||||
@@ -718,6 +725,13 @@ cdef _setDynamicFieldPtr(_DynamicSetterClasses * thisptr, field, value, parent):
|
|||||||
builder = to_python_builder(thisptr.init(field, len(value)), parent)
|
builder = to_python_builder(thisptr.init(field, len(value)), parent)
|
||||||
for (i, v) in enumerate(value):
|
for (i, v) in enumerate(value):
|
||||||
builder[i] = v
|
builder[i] = v
|
||||||
|
elif value_type is dict:
|
||||||
|
if (_DynamicSetterClasses is DynamicStruct_Builder or _DynamicSetterClasses is Request):
|
||||||
|
builder = to_python_builder(thisptr.get(field), parent)
|
||||||
|
_from_dict(builder, value)
|
||||||
|
else:
|
||||||
|
builder = to_python_builder(thisptr[field], parent)
|
||||||
|
_from_dict(builder, value)
|
||||||
elif value is None:
|
elif value is None:
|
||||||
temp = C_DynamicValue.Reader(VOID)
|
temp = C_DynamicValue.Reader(VOID)
|
||||||
thisptr.set(field, temp)
|
thisptr.set(field, temp)
|
||||||
@@ -869,11 +883,11 @@ cdef class _DynamicStructBuilder:
|
|||||||
setattr(person, 'field-with-hyphens', 'foo') # for names that are invalid for python, use setattr
|
setattr(person, 'field-with-hyphens', 'foo') # for names that are invalid for python, use setattr
|
||||||
print getattr(person, 'field-with-hyphens') # for names that are invalid for python, use getattr
|
print getattr(person, 'field-with-hyphens') # for names that are invalid for python, use getattr
|
||||||
"""
|
"""
|
||||||
cdef C_DynamicStruct.Builder thisptr
|
cdef DynamicStruct_Builder thisptr
|
||||||
cdef public object _parent
|
cdef public object _parent
|
||||||
cdef public bint is_root
|
cdef public bint is_root
|
||||||
cdef bint _is_written
|
cdef bint _is_written
|
||||||
cdef _init(self, C_DynamicStruct.Builder other, object parent, bint isRoot = False):
|
cdef _init(self, DynamicStruct_Builder other, object parent, bint isRoot = False):
|
||||||
self.thisptr = other
|
self.thisptr = other
|
||||||
self._parent = parent
|
self._parent = parent
|
||||||
self.is_root = isRoot
|
self.is_root = isRoot
|
||||||
@@ -1496,7 +1510,7 @@ cdef class _Request(_DynamicStructBuilder):
|
|||||||
|
|
||||||
cdef _init_child(self, Request other, parent):
|
cdef _init_child(self, Request other, parent):
|
||||||
self.thisptr_child = new Request(moveRequest(other))
|
self.thisptr_child = new Request(moveRequest(other))
|
||||||
self._init(<C_DynamicStruct.Builder>deref(self.thisptr_child), parent)
|
self._init(<DynamicStruct_Builder>deref(self.thisptr_child), parent)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def __dealloc__(self):
|
def __dealloc__(self):
|
||||||
|
|||||||
@@ -106,3 +106,31 @@ def test_unicode_str(all_types):
|
|||||||
msg.textField = "f\u00e6oo"
|
msg.textField = "f\u00e6oo"
|
||||||
|
|
||||||
assert msg.textField == "f\u00e6oo"
|
assert msg.textField == "f\u00e6oo"
|
||||||
|
|
||||||
|
|
||||||
|
def test_new_message(all_types):
|
||||||
|
msg = all_types.TestAllTypes.new_message(int32Field=100)
|
||||||
|
|
||||||
|
assert msg.int32Field == 100
|
||||||
|
|
||||||
|
msg = all_types.TestAllTypes.new_message(structField={'int32Field': 100})
|
||||||
|
|
||||||
|
assert msg.structField.int32Field == 100
|
||||||
|
|
||||||
|
msg = all_types.TestAllTypes.new_message(structList=[{'int32Field': 100}, {'int32Field': 101}])
|
||||||
|
|
||||||
|
assert msg.structList[0].int32Field == 100
|
||||||
|
assert msg.structList[1].int32Field == 101
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_dict(all_types):
|
||||||
|
msg = all_types.TestAllTypes.new_message()
|
||||||
|
|
||||||
|
msg.structField = {'int32Field': 100}
|
||||||
|
|
||||||
|
assert msg.structField.int32Field == 100
|
||||||
|
|
||||||
|
msg.init('structList', 2)
|
||||||
|
msg.structList[0] = {'int32Field': 102}
|
||||||
|
|
||||||
|
assert msg.structList[0].int32Field == 102
|
||||||
|
|||||||
Reference in New Issue
Block a user