]> git.notmuchmail.org Git - notmuch/blobdiff - bindings/python-cffi/notmuch2/_message.py
python/notmuch2: do not destroy messages owned by a query
[notmuch] / bindings / python-cffi / notmuch2 / _message.py
index bb5614260e8046a1ceb4e7b3450d0200ab684939..416ce7ca609a1a6d2f1f93b5c208af64cf6c9c3e 100644 (file)
@@ -14,7 +14,7 @@ __all__ = ['Message']
 
 
 class Message(base.NotmuchObject):
-    """An email message stored in the notmuch database.
+    """An email message stored in the notmuch database retrieved via a query.
 
     This should not be directly created, instead it will be returned
     by calling methods on :class:`Database`.  A message keeps a
@@ -61,22 +61,10 @@ class Message(base.NotmuchObject):
 
     @property
     def alive(self):
-        if not self._parent.alive:
-            return False
-        try:
-            self._msg_p
-        except errors.ObjectDestroyedError:
-            return False
-        else:
-            return True
-
-    def __del__(self):
-        self._destroy()
+        return self._parent.alive
 
     def _destroy(self):
-        if self.alive:
-            capi.lib.notmuch_message_destroy(self._msg_p)
-        self._msg_p = None
+        pass
 
     @property
     def messageid(self):
@@ -98,7 +86,7 @@ class Message(base.NotmuchObject):
            bytes() on it will return the original bytes used to create
            it.
 
-        :raises ObjectDestroyedError: if used after destoryed.
+        :raises ObjectDestroyedError: if used after destroyed.
         """
         ret = capi.lib.notmuch_message_get_message_id(self._msg_p)
         return base.BinString(capi.ffi.string(ret))
@@ -116,7 +104,7 @@ class Message(base.NotmuchObject):
            bytes() on it will return the original bytes used to create
            it.
 
-        :raises ObjectDestroyedError: if used after destoryed.
+        :raises ObjectDestroyedError: if used after destroyed.
         """
         ret = capi.lib.notmuch_message_get_thread_id(self._msg_p)
         return base.BinString(capi.ffi.string(ret))
@@ -128,7 +116,7 @@ class Message(base.NotmuchObject):
         If multiple files in the database contain the same message ID
         this will be just one of the files, chosen at random.
 
-        :raises ObjectDestroyedError: if used after destoryed.
+        :raises ObjectDestroyedError: if used after destroyed.
         """
         ret = capi.lib.notmuch_message_get_filename(self._msg_p)
         return pathlib.Path(os.fsdecode(capi.ffi.string(ret)))
@@ -140,7 +128,7 @@ class Message(base.NotmuchObject):
         See :attr:`path` for details, this is the same but does return
         the path as a bytes object which is faster but less convenient.
 
-        :raises ObjectDestroyedError: if used after destoryed.
+        :raises ObjectDestroyedError: if used after destroyed.
         """
         ret = capi.lib.notmuch_message_get_filename(self._msg_p)
         return capi.ffi.string(ret)
@@ -155,7 +143,7 @@ class Message(base.NotmuchObject):
         :returns: Iterator yielding :class:`pathlib.Path` instances.
         :rtype: iter
 
-        :raises ObjectDestroyedError: if used after destoryed.
+        :raises ObjectDestroyedError: if used after destroyed.
         """
         fnames_p = capi.lib.notmuch_message_get_filenames(self._msg_p)
         return PathIter(self, fnames_p)
@@ -169,7 +157,7 @@ class Message(base.NotmuchObject):
         :returns: Iterator yielding :class:`bytes` instances.
         :rtype: iter
 
-        :raises ObjectDestroyedError: if used after destoryed.
+        :raises ObjectDestroyedError: if used after destroyed.
         """
         fnames_p = capi.lib.notmuch_message_get_filenames(self._msg_p)
         return FilenamesIter(self, fnames_p)
@@ -184,7 +172,7 @@ class Message(base.NotmuchObject):
         :attr:`messageid` and :attr:`threadid` attributes are valid
         for it.
 
-        :raises ObjectDestroyedError: if used after destoryed.
+        :raises ObjectDestroyedError: if used after destroyed.
         """
         ret = capi.lib.notmuch_message_get_flag(
             self._msg_p, capi.lib.NOTMUCH_MESSAGE_FLAG_GHOST)
@@ -201,7 +189,7 @@ class Message(base.NotmuchObject):
         these messages to be flagged, which results in this property
         being set to *True*.
 
-        :raises ObjectDestroyedError: if used after destoryed.
+        :raises ObjectDestroyedError: if used after destroyed.
         """
         ret = capi.lib.notmuch_message_get_flag(
             self._msg_p, capi.lib.NOTMUCH_MESSAGE_FLAG_EXCLUDED)
@@ -216,7 +204,7 @@ class Message(base.NotmuchObject):
         message's header, you can get the original header value with
         :meth:`header`.
 
-        :raises ObjectDestroyedError: if used after destoryed.
+        :raises ObjectDestroyedError: if used after destroyed.
         """
         return capi.lib.notmuch_message_get_date(self._msg_p)
 
@@ -240,7 +228,7 @@ class Message(base.NotmuchObject):
 
         :raises LookupError: if the header is not present.
         :raises NullPointerError: For unexpected notmuch errors.
-        :raises ObjectDestroyedError: if used after destoryed.
+        :raises ObjectDestroyedError: if used after destroyed.
         """
         # The returned is supposedly guaranteed to be UTF-8.  Header
         # names must be ASCII as per RFC x822.
@@ -263,7 +251,7 @@ class Message(base.NotmuchObject):
 
         :raises ReadOnlyDatabaseError: When manipulating tags on a
            database opened in read-only mode.
-        :raises ObjectDestroyedError: if used after destoryed.
+        :raises ObjectDestroyedError: if used after destroyed.
         """
         try:
             ref = self._cached_tagset
@@ -297,7 +285,7 @@ class Message(base.NotmuchObject):
         :raises UnbalancedFreezeThawError: if you somehow managed to
            call __exit__ of this context manager more than once.  Why
            did you do that?
-        :raises ObjectDestroyedError: if used after destoryed.
+        :raises ObjectDestroyedError: if used after destroyed.
         """
         ret = capi.lib.notmuch_message_freeze(self._msg_p)
         if ret != capi.lib.NOTMUCH_STATUS_SUCCESS:
@@ -375,6 +363,30 @@ class Message(base.NotmuchObject):
         if isinstance(other, self.__class__):
             return self.messageid == other.messageid
 
+class StandaloneMessage(Message):
+    """An email message stored in the notmuch database.
+
+    This subclass of Message is used for messages that are retrieved from the
+    database directly and are not owned by a query.
+    """
+    @property
+    def alive(self):
+        if not self._parent.alive:
+            return False
+        try:
+            self._msg_p
+        except errors.ObjectDestroyedError:
+            return False
+        else:
+            return True
+
+    def __del__(self):
+        self._destroy()
+
+    def _destroy(self):
+        if self.alive:
+            capi.lib.notmuch_message_destroy(self._msg_p)
+        self._msg_p = None
 
 class FilenamesIter(base.NotmuchIter):
     """Iterator for binary filenames objects."""