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 isEnum()
|
||||||
cbool isStruct()
|
cbool isStruct()
|
||||||
cbool isInterface()
|
cbool isInterface()
|
||||||
|
cbool isData()
|
||||||
|
|
||||||
StructSchema asStruct() except +reraise_kj_exception
|
StructSchema asStruct() except +reraise_kj_exception
|
||||||
EnumSchema asEnum() 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 getUnionFields()
|
||||||
FieldSubset getNonUnionFields()
|
FieldSubset getNonUnionFields()
|
||||||
|
|
||||||
Field getFieldByName(char * name)
|
Field getFieldByName(char * name) except +reraise_kj_exception
|
||||||
|
|
||||||
cbool operator == (StructSchema)
|
cbool operator == (StructSchema)
|
||||||
|
|
||||||
|
|||||||
@@ -1879,9 +1879,8 @@ cdef class _DynamicStructBuilder:
|
|||||||
for key, val in d.iteritems():
|
for key, val in d.iteritems():
|
||||||
if key != 'which':
|
if key != 'which':
|
||||||
if isinstance(val, str):
|
if isinstance(val, str):
|
||||||
field = self.schema.fields.get(key)
|
key_bytes = key.encode()
|
||||||
dtype = field.proto.slot.type.which()
|
if self.thisptr.getSchema().getFieldByName(key_bytes).getType().isData():
|
||||||
if dtype == "data":
|
|
||||||
# decode bytes from utf-8 base64 encoding
|
# decode bytes from utf-8 base64 encoding
|
||||||
val = base64.b64decode(val)
|
val = base64.b64decode(val)
|
||||||
try:
|
try:
|
||||||
|
|||||||
Reference in New Issue
Block a user