fix: check field type via C++ schema in from_dict to avoid a reference cycle (#407)
from_dict called self.schema.fields for str values, which builds _StructSchemaField wrappers that reference the schema, so every message built via kwargs stayed alive until a GC pass. Follow-up to #401, which only skipped the lookup for non-str values.
This commit is contained in:
@@ -128,6 +128,7 @@ cdef extern from "capnp/schema.h" namespace " ::capnp":
|
||||
cbool isEnum()
|
||||
cbool isStruct()
|
||||
cbool isInterface()
|
||||
cbool isData()
|
||||
|
||||
StructSchema asStruct() except +reraise_kj_exception
|
||||
EnumSchema asEnum() except +reraise_kj_exception
|
||||
@@ -185,7 +186,7 @@ cdef extern from "capnp/schema.h" namespace " ::capnp":
|
||||
FieldSubset getUnionFields()
|
||||
FieldSubset getNonUnionFields()
|
||||
|
||||
Field getFieldByName(char * name)
|
||||
Field getFieldByName(char * name) except +reraise_kj_exception
|
||||
|
||||
cbool operator == (StructSchema)
|
||||
|
||||
|
||||
@@ -1879,9 +1879,8 @@ cdef class _DynamicStructBuilder:
|
||||
for key, val in d.iteritems():
|
||||
if key != 'which':
|
||||
if isinstance(val, str):
|
||||
field = self.schema.fields.get(key)
|
||||
dtype = field.proto.slot.type.which()
|
||||
if dtype == "data":
|
||||
key_bytes = key.encode()
|
||||
if self.thisptr.getSchema().getFieldByName(key_bytes).getType().isData():
|
||||
# decode bytes from utf-8 base64 encoding
|
||||
val = base64.b64decode(val)
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user