Add warning when writing the same message more than once

This commit is contained in:
Jason Paryani
2013-10-20 22:44:15 -07:00
parent d7abfae1ed
commit f947e3270f

View File

@@ -670,13 +670,20 @@ cdef class _DynamicStructBuilder:
""" """
cdef C_DynamicStruct.Builder thisptr cdef C_DynamicStruct.Builder thisptr
cdef public object _parent 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): cdef _init(self, C_DynamicStruct.Builder other, object parent, bint isRoot = False):
self.thisptr = other self.thisptr = other
self._parent = parent self._parent = parent
self._isRoot = isRoot self._is_root = isRoot
self._is_written = False
return self 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): def write(self, file):
"""Writes the struct's containing message to the given file object in unpacked binary format. """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. :Raises: :exc:`exceptions.ValueError` if this isn't the message's root struct.
""" """
if not self._isRoot: self._check_write()
raise ValueError("You can only call write() on the message's root struct.")
_write_message_to_fd(file.fileno(), self._parent) _write_message_to_fd(file.fileno(), self._parent)
self._is_written = True
def write_packed(self, file): def write_packed(self, file):
"""Writes the struct's containing message to the given file object in packed binary format. """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. :Raises: :exc:`exceptions.ValueError` if this isn't the message's root struct.
""" """
if not self._isRoot: self._check_write()
raise ValueError("You can only call write() on the message's root struct.")
_write_packed_message_to_fd(file.fileno(), self._parent) _write_packed_message_to_fd(file.fileno(), self._parent)
self._is_written = True
def to_bytes(_DynamicStructBuilder self): def to_bytes(_DynamicStructBuilder self):
"""Returns the struct's containing message as a Python bytes object in the unpacked binary format. """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. :Raises: :exc:`exceptions.ValueError` if this isn't the message's root struct.
""" """
if not self._isRoot: self._check_write()
raise ValueError("You can only call write() on the message's root struct.")
cdef _MessageBuilder builder = self._parent cdef _MessageBuilder builder = self._parent
array = schema_cpp.messageToFlatArray(deref(builder.thisptr)) array = schema_cpp.messageToFlatArray(deref(builder.thisptr))
cdef const char* ptr = <const char *>array.begin() cdef const char* ptr = <const char *>array.begin()
cdef bytes ret = ptr[:8*array.size()] cdef bytes ret = ptr[:8*array.size()]
self._is_written = True
return ret return ret
cdef _get(self, field): cdef _get(self, field):