From f947e3270f0026df43fbb511e6b6266293d1a44c Mon Sep 17 00:00:00 2001 From: Jason Paryani Date: Sun, 20 Oct 2013 22:44:15 -0700 Subject: [PATCH] Add warning when writing the same message more than once --- capnp/capnp.pyx | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/capnp/capnp.pyx b/capnp/capnp.pyx index fbc51d2..d68eb5b 100644 --- a/capnp/capnp.pyx +++ b/capnp/capnp.pyx @@ -670,13 +670,20 @@ cdef class _DynamicStructBuilder: """ cdef C_DynamicStruct.Builder thisptr cdef public object _parent - cdef bint _isRoot + cdef bint _is_root, _is_written cdef _init(self, C_DynamicStruct.Builder other, object parent, bint isRoot = False): self.thisptr = other self._parent = parent - self._isRoot = isRoot + self._is_root = isRoot + self._is_written = False return self - + + cdef _check_write(self): + if not self._is_root: + raise ValueError("You can only call write() on the message's root struct.") + if self._is_written: + _warnings.warn("This message has already been written once. Be very careful that you're not setting Text/Struct/List fields more than once, since that will cause memory leaks (both in memory and in the serialized data). You can disable this warning by setting the `_is_written` field of this object to False after every write.") + def write(self, file): """Writes the struct's containing message to the given file object in unpacked binary format. @@ -690,9 +697,9 @@ cdef class _DynamicStructBuilder: :Raises: :exc:`exceptions.ValueError` if this isn't the message's root struct. """ - if not self._isRoot: - raise ValueError("You can only call write() on the message's root struct.") + self._check_write() _write_message_to_fd(file.fileno(), self._parent) + self._is_written = True def write_packed(self, file): """Writes the struct's containing message to the given file object in packed binary format. @@ -707,9 +714,9 @@ cdef class _DynamicStructBuilder: :Raises: :exc:`exceptions.ValueError` if this isn't the message's root struct. """ - if not self._isRoot: - raise ValueError("You can only call write() on the message's root struct.") + self._check_write() _write_packed_message_to_fd(file.fileno(), self._parent) + self._is_written = True def to_bytes(_DynamicStructBuilder self): """Returns the struct's containing message as a Python bytes object in the unpacked binary format. @@ -720,12 +727,12 @@ cdef class _DynamicStructBuilder: :Raises: :exc:`exceptions.ValueError` if this isn't the message's root struct. """ - if not self._isRoot: - raise ValueError("You can only call write() on the message's root struct.") + self._check_write() cdef _MessageBuilder builder = self._parent array = schema_cpp.messageToFlatArray(deref(builder.thisptr)) cdef const char* ptr = array.begin() cdef bytes ret = ptr[:8*array.size()] + self._is_written = True return ret cdef _get(self, field):