]> git.notmuchmail.org Git - notmuch/blobdiff - bindings/python-cffi/notmuch2/_message.py
emacs: Add new option notmuch-search-hide-excluded
[notmuch] / bindings / python-cffi / notmuch2 / _message.py
index bb5614260e8046a1ceb4e7b3450d0200ab684939..d4b34e91e2f88ff367a73cfa5b311d11cbfa6b9a 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
@@ -26,7 +26,7 @@ class Message(base.NotmuchObject):
     package from Python's standard library.  You could e.g. create
     this as such::
 
     package from Python's standard library.  You could e.g. create
     this as such::
 
-       notmuch_msg = db.get_message(msgid)  # or from a query
+       notmuch_msg = db.find(msgid)  # or from a query
        parser = email.parser.BytesParser(policy=email.policy.default)
        with notmuch_msg.path.open('rb) as fp:
            email_msg = parser.parse(fp)
        parser = email.parser.BytesParser(policy=email.policy.default)
        with notmuch_msg.path.open('rb) as fp:
            email_msg = parser.parse(fp)
@@ -47,9 +47,7 @@ class Message(base.NotmuchObject):
     :type db: Database
     :param msg_p: The C pointer to the ``notmuch_message_t``.
     :type msg_p: <cdata>
     :type db: Database
     :param msg_p: The C pointer to the ``notmuch_message_t``.
     :type msg_p: <cdata>
-
     :param dup: Whether the message was a duplicate on insertion.
     :param dup: Whether the message was a duplicate on insertion.
-
     :type dup: None or bool
     """
     _msg_p = base.MemoryPointer()
     :type dup: None or bool
     """
     _msg_p = base.MemoryPointer()
@@ -98,7 +96,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 +114,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 +126,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 +138,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)
@@ -149,13 +147,13 @@ class Message(base.NotmuchObject):
         """Return an iterator of all files for this message.
 
         If multiple files contained the same message ID they will all
         """Return an iterator of all files for this message.
 
         If multiple files contained the same message ID they will all
-        be returned here.  The files are returned as intances of
+        be returned here.  The files are returned as instances of
         :class:`pathlib.Path`.
 
         :returns: Iterator yielding :class:`pathlib.Path` instances.
         :rtype: iter
 
         :class:`pathlib.Path`.
 
         :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 +167,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 +182,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,12 +199,26 @@ 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)
         return bool(ret)
 
         """
         ret = capi.lib.notmuch_message_get_flag(
             self._msg_p, capi.lib.NOTMUCH_MESSAGE_FLAG_EXCLUDED)
         return bool(ret)
 
+    @property
+    def matched(self):
+        """Indicates whether this message was matched by the query.
+
+        When a thread is created from a search, some of the
+        messages may not match the original query.  This property
+        is set to *True* for those that do match.
+
+        :raises ObjectDestroyedError: if used after destroyed.
+        """
+        ret = capi.lib.notmuch_message_get_flag(
+            self._msg_p, capi.lib.NOTMUCH_MESSAGE_FLAG_MATCH)
+        return bool(ret)
+
     @property
     def date(self):
         """The message date as an integer.
     @property
     def date(self):
         """The message date as an integer.
@@ -216,7 +228,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 +252,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 +275,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 +309,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:
@@ -359,14 +371,14 @@ class Message(base.NotmuchObject):
         This method will only work if the message was created from a
         thread.  Otherwise it will yield no results.
 
         This method will only work if the message was created from a
         thread.  Otherwise it will yield no results.
 
-        :returns: An iterator yielding :class:`Message` instances.
+        :returns: An iterator yielding :class:`OwnedMessage` instances.
         :rtype: MessageIter
         """
         # The notmuch_messages_valid call accepts NULL and this will
         # become an empty iterator, raising StopIteration immediately.
         # Hence no return value checking here.
         msgs_p = capi.lib.notmuch_message_get_replies(self._msg_p)
         :rtype: MessageIter
         """
         # The notmuch_messages_valid call accepts NULL and this will
         # become an empty iterator, raising StopIteration immediately.
         # Hence no return value checking here.
         msgs_p = capi.lib.notmuch_message_get_replies(self._msg_p)
-        return MessageIter(self, msgs_p, db=self._db)
+        return MessageIter(self, msgs_p, db=self._db, msg_cls=OwnedMessage)
 
     def __hash__(self):
         return hash(self.messageid)
 
     def __hash__(self):
         return hash(self.messageid)
@@ -376,6 +388,26 @@ class Message(base.NotmuchObject):
             return self.messageid == other.messageid
 
 
             return self.messageid == other.messageid
 
 
+class OwnedMessage(Message):
+    """An email message owned by parent thread object.
+
+    This subclass of Message is used for messages that are retrieved
+    from the notmuch database via a parent :class:`notmuch2.Thread`
+    object, which "owns" this message.  This means that when this
+    message object is destroyed, by calling :func:`del` or
+    :meth:`_destroy` directly or indirectly, the message is not freed
+    in the notmuch API and the parent :class:`notmuch2.Thread` object
+    can return the same object again when needed.
+    """
+
+    @property
+    def alive(self):
+        return self._parent.alive
+
+    def _destroy(self):
+        pass
+
+
 class FilenamesIter(base.NotmuchIter):
     """Iterator for binary filenames objects."""
 
 class FilenamesIter(base.NotmuchIter):
     """Iterator for binary filenames objects."""
 
@@ -413,7 +445,7 @@ class PropertiesMap(base.NotmuchObject, collections.abc.MutableMapping):
     means the former will yield duplicate keys while the latter won't.
     It also means ``len(list(iter(this_map)))`` could be different
     than ``len(this_map.keys())``.  ``len(this_map)`` will correspond
     means the former will yield duplicate keys while the latter won't.
     It also means ``len(list(iter(this_map)))`` could be different
     than ``len(this_map.keys())``.  ``len(this_map)`` will correspond
-    with the lenght of the default iterator.
+    with the length of the default iterator.
 
     Be aware that libnotmuch exposes all of this as iterators, so
     quite a few operations have O(n) performance instead of the usual
 
     Be aware that libnotmuch exposes all of this as iterators, so
     quite a few operations have O(n) performance instead of the usual
@@ -678,8 +710,9 @@ collections.abc.ValuesView.register(PropertiesValuesView)
 
 class MessageIter(base.NotmuchIter):
 
 
 class MessageIter(base.NotmuchIter):
 
-    def __init__(self, parent, msgs_p, *, db):
+    def __init__(self, parent, msgs_p, *, db, msg_cls=Message):
         self._db = db
         self._db = db
+        self._msg_cls = msg_cls
         super().__init__(parent, msgs_p,
                          fn_destroy=capi.lib.notmuch_messages_destroy,
                          fn_valid=capi.lib.notmuch_messages_valid,
         super().__init__(parent, msgs_p,
                          fn_destroy=capi.lib.notmuch_messages_destroy,
                          fn_valid=capi.lib.notmuch_messages_valid,
@@ -688,4 +721,4 @@ class MessageIter(base.NotmuchIter):
 
     def __next__(self):
         msg_p = super().__next__()
 
     def __next__(self):
         msg_p = super().__next__()
-        return Message(self, msg_p, db=self._db)
+        return self._msg_cls(self, msg_p, db=self._db)