]> 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):
 
 
 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
 
     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):
 
     @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):
 
     def _destroy(self):
-        if self.alive:
-            capi.lib.notmuch_message_destroy(self._msg_p)
-        self._msg_p = None
+        pass
 
     @property
     def messageid(self):
 
     @property
     def messageid(self):
@@ -98,7 +86,7 @@ class Message(base.NotmuchObject):
            bytes() on it will return the original bytes used to create
            it.
 
            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))
         """
         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.
 
            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))
         """
         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.
 
         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)))
         """
         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.
 
         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)
         """
         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
 
         :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)
         """
         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
 
         :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)
         """
         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.
 
         :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)
         """
         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*.
 
         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)
         """
         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`.
 
         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)
 
         """
         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 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.
         """
         # 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 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
         """
         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 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:
         """
         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
 
         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."""
 
 class FilenamesIter(base.NotmuchIter):
     """Iterator for binary filenames objects."""