]> git.notmuchmail.org Git - notmuch/commitdiff
python: refactor the error handling machinery
authorJustus Winter <4winter@informatik.uni-hamburg.de>
Mon, 20 Feb 2012 22:49:07 +0000 (23:49 +0100)
committerJustus Winter <4winter@informatik.uni-hamburg.de>
Mon, 20 Feb 2012 22:49:07 +0000 (23:49 +0100)
Raise specific error classes instead of a generic NotmuchError with an
magic status value (e.g. NotmuchError(STATUS.NULL_POINTER) ->
NullPointerError()), update the documentation accordingly.

Signed-off-by: Justus Winter <4winter@informatik.uni-hamburg.de>
bindings/python/notmuch/database.py
bindings/python/notmuch/filename.py
bindings/python/notmuch/message.py
bindings/python/notmuch/tag.py
bindings/python/notmuch/thread.py

index 6edb18b69d845514dbbe5ad9e7a960e96ad4b184..3de0f2b8997a8dc04032c875e4bc2b592cbf44b0 100644 (file)
@@ -23,7 +23,9 @@ from ctypes import c_char_p, c_void_p, c_uint, c_long, byref, POINTER
 from notmuch.globals import (
     nmlib,
     STATUS,
 from notmuch.globals import (
     nmlib,
     STATUS,
+    FileError,
     NotmuchError,
     NotmuchError,
+    NullPointerError,
     NotInitializedError,
     Enum,
     _str,
     NotInitializedError,
     Enum,
     _str,
@@ -355,9 +357,8 @@ class Database(object):
             # we got an absolute path
             if not path.startswith(self.get_path()):
                 # but its initial components are not equal to the db path
             # we got an absolute path
             if not path.startswith(self.get_path()):
                 # but its initial components are not equal to the db path
-                raise NotmuchError(STATUS.FILE_ERROR,
-                                   message="Database().get_directory() called "
-                                           "with a wrong absolute path.")
+                raise FileError('Database().get_directory() called '
+                                'with a wrong absolute path')
             abs_dirpath = path
         else:
             #we got a relative path, make it absolute
             abs_dirpath = path
         else:
             #we got a relative path, make it absolute
@@ -542,7 +543,7 @@ class Database(object):
         self._assert_db_is_initialized()
         tags_p = Database._get_all_tags(self._db)
         if tags_p == None:
         self._assert_db_is_initialized()
         tags_p = Database._get_all_tags(self._db)
         if tags_p == None:
-            raise NotmuchError(STATUS.NULL_POINTER)
+            raise NullPointerError()
         return Tags(tags_p, self)
 
     def create_query(self, querystring):
         return Tags(tags_p, self)
 
     def create_query(self, querystring):
@@ -636,7 +637,7 @@ class Directory(object):
         """Raises a NotmuchError(:attr:`STATUS`.NOT_INITIALIZED)
         if dir_p is None"""
         if not self._dir_p:
         """Raises a NotmuchError(:attr:`STATUS`.NOT_INITIALIZED)
         if dir_p is None"""
         if not self._dir_p:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
 
     def __init__(self, path, dir_p, parent):
         """
 
     def __init__(self, path, dir_p, parent):
         """
@@ -797,7 +798,7 @@ class Filenames(object):
 
     def __next__(self):
         if not self._files_p:
 
     def __next__(self):
         if not self._files_p:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
 
         if not self._valid(self._files_p):
             self._files_p = None
 
         if not self._valid(self._files_p):
             self._files_p = None
@@ -824,7 +825,7 @@ class Filenames(object):
                      for file in files: print file
         """
         if not self._files_p:
                      for file in files: print file
         """
         if not self._files_p:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
 
         i = 0
         while self._valid(self._files_p):
 
         i = 0
         while self._valid(self._files_p):
index 322e6bf135b19ed8bc5f0b852e1a5d6b3fda5535..353eb76e3e946f7b480eca634640fcbdf405bba9 100644 (file)
@@ -17,8 +17,14 @@ along with notmuch.  If not, see <http://www.gnu.org/licenses/>.
 Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>'
 """
 from ctypes import c_char_p
 Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>'
 """
 from ctypes import c_char_p
-from notmuch.globals import (nmlib, STATUS, NotmuchError,
-    NotmuchFilenamesP, NotmuchMessageP, Python3StringMixIn)
+from notmuch.globals import (
+    nmlib,
+    NullPointerError,
+    NotInitializedError,
+    NotmuchMessageP,
+    NotmuchFilenamesP,
+    Python3StringMixIn,
+)
 
 
 class Filenames(Python3StringMixIn):
 
 
 class Filenames(Python3StringMixIn):
@@ -29,9 +35,9 @@ class Filenames(Python3StringMixIn):
     iterator over a list of notmuch filenames. Do note that the underlying
     library only provides a one-time iterator (it cannot reset the iterator to
     the start). Thus iterating over the function will "exhaust" the list of
     iterator over a list of notmuch filenames. Do note that the underlying
     library only provides a one-time iterator (it cannot reset the iterator to
     the start). Thus iterating over the function will "exhaust" the list of
-    tags, and a subsequent iteration attempt will raise a :exc:`NotmuchError`
-    STATUS.NOT_INITIALIZED. Also note, that any function that uses iteration
-    (nearly all) will also exhaust the tags. So both::
+    tags, and a subsequent iteration attempt will raise a
+    :exc:`NotInitializedError`. Also note, that any function that uses
+    iteration (nearly all) will also exhaust the tags. So both::
 
       for name in filenames: print name
 
 
       for name in filenames: print name
 
@@ -61,8 +67,8 @@ class Filenames(Python3StringMixIn):
              will almost never instantiate a :class:`Tags` object
              herself. They are usually handed back as a result,
              e.g. in :meth:`Database.get_all_tags`.  *tags_p* must be
              will almost never instantiate a :class:`Tags` object
              herself. They are usually handed back as a result,
              e.g. in :meth:`Database.get_all_tags`.  *tags_p* must be
-             valid, we will raise an :exc:`NotmuchError`
-             (STATUS.NULL_POINTER) if it is `None`.
+             valid, we will raise an :exc:`NullPointerError`
+             if it is `None`.
         :type files_p: :class:`ctypes.c_void_p`
         :param parent: The parent object (ie :class:`Message` these
              filenames are derived from, and saves a
         :type files_p: :class:`ctypes.c_void_p`
         :param parent: The parent object (ie :class:`Message` these
              filenames are derived from, and saves a
@@ -70,7 +76,7 @@ class Filenames(Python3StringMixIn):
              once all derived objects are dead.
         """
         if not files_p:
              once all derived objects are dead.
         """
         if not files_p:
-            raise NotmuchError(STATUS.NULL_POINTER)
+            raise NullPointerError()
 
         self._files = files_p
         #save reference to parent object so we keep it alive
 
         self._files = files_p
         #save reference to parent object so we keep it alive
@@ -90,7 +96,7 @@ class Filenames(Python3StringMixIn):
         This is the main function that will usually be used by the
         user."""
         if not self._files:
         This is the main function that will usually be used by the
         user."""
         if not self._files:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
 
         while self._valid(self._files):
             yield Filenames._get(self._files).decode('utf-8', 'ignore')
 
         while self._valid(self._files):
             yield Filenames._get(self._files).decode('utf-8', 'ignore')
@@ -104,7 +110,7 @@ class Filenames(Python3StringMixIn):
         .. note:: As this iterates over the filenames, we will not be
                able to iterate over them again (as in retrieve them)! If
                the tags have been exhausted already, this will raise a
         .. note:: As this iterates over the filenames, we will not be
                able to iterate over them again (as in retrieve them)! If
                the tags have been exhausted already, this will raise a
-               :exc:`NotmuchError` STATUS.NOT_INITIALIZED on subsequent
+               :exc:`NotInitializedError` on subsequent
                attempts. However, you can use
                :meth:`Message.get_filenames` repeatedly to perform
                various actions on filenames.
                attempts. However, you can use
                :meth:`Message.get_filenames` repeatedly to perform
                various actions on filenames.
index 28723c10c246c871dcf7fb03d5f534c4d63d4ed8..b291f9fa4e8748c87b2c36912e33e47726a432f3 100644 (file)
@@ -22,8 +22,19 @@ Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>'
 from ctypes import c_char_p, c_long, c_uint, c_int
 from datetime import date
 from notmuch.globals import (
 from ctypes import c_char_p, c_long, c_uint, c_int
 from datetime import date
 from notmuch.globals import (
-    nmlib, STATUS, NotmuchError, Enum, _str, Python3StringMixIn,
-    NotmuchTagsP, NotmuchMessagesP, NotmuchMessageP, NotmuchFilenamesP)
+    nmlib,
+    Enum,
+    _str,
+    Python3StringMixIn,
+    STATUS,
+    NotmuchError,
+    NullPointerError,
+    NotInitializedError,
+    NotmuchTagsP,
+    NotmuchMessageP,
+    NotmuchMessagesP,
+    NotmuchFilenamesP,
+)
 from notmuch.tag import Tags
 from notmuch.filename import Filenames
 import sys
 from notmuch.tag import Tags
 from notmuch.filename import Filenames
 import sys
@@ -43,7 +54,7 @@ class Messages(object):
     only provides a one-time iterator (it cannot reset the iterator to
     the start). Thus iterating over the function will "exhaust" the list
     of messages, and a subsequent iteration attempt will raise a
     only provides a one-time iterator (it cannot reset the iterator to
     the start). Thus iterating over the function will "exhaust" the list
     of messages, and a subsequent iteration attempt will raise a
-    :exc:`NotmuchError` STATUS.NOT_INITIALIZED. If you need to
+    :exc:`NotInitializedError`. If you need to
     re-iterate over a list of messages you will need to retrieve a new
     :class:`Messages` object or cache your :class:`Message`\s in a list
     via::
     re-iterate over a list of messages you will need to retrieve a new
     :class:`Messages` object or cache your :class:`Message`\s in a list
     via::
@@ -107,8 +118,8 @@ class Messages(object):
              will almost never instantiate a :class:`Messages` object
              herself. They are usually handed back as a result,
              e.g. in :meth:`Query.search_messages`.  *msgs_p* must be
              will almost never instantiate a :class:`Messages` object
              herself. They are usually handed back as a result,
              e.g. in :meth:`Query.search_messages`.  *msgs_p* must be
-             valid, we will raise an :exc:`NotmuchError`
-             (STATUS.NULL_POINTER) if it is `None`.
+             valid, we will raise an :exc:`NullPointerError` if it is
+             `None`.
         :type msgs_p: :class:`ctypes.c_void_p`
         :param parent: The parent object
              (ie :class:`Query`) these tags are derived from. It saves
         :type msgs_p: :class:`ctypes.c_void_p`
         :param parent: The parent object
              (ie :class:`Query`) these tags are derived from. It saves
@@ -118,7 +129,7 @@ class Messages(object):
                the Python object.(?)
         """
         if not msgs_p:
                the Python object.(?)
         """
         if not msgs_p:
-            raise NotmuchError(STATUS.NULL_POINTER)
+            raise NullPointerError()
 
         self._msgs = msgs_p
         #store parent, so we keep them alive as long as self  is alive
 
         self._msgs = msgs_p
         #store parent, so we keep them alive as long as self  is alive
@@ -128,7 +139,7 @@ class Messages(object):
         """Return the unique :class:`Tags` in the contained messages
 
         :returns: :class:`Tags`
         """Return the unique :class:`Tags` in the contained messages
 
         :returns: :class:`Tags`
-        :exceptions: :exc:`NotmuchError` STATUS.NOT_INITIALIZED if not init'ed
+        :exceptions: :exc:`NotInitializedError` if not init'ed
 
         .. note::
 
 
         .. note::
 
@@ -136,7 +147,7 @@ class Messages(object):
             will not allow further iterations.
         """
         if not self._msgs:
             will not allow further iterations.
         """
         if not self._msgs:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
 
         # collect all tags (returns NULL on error)
         tags_p = Messages._collect_tags(self._msgs)
 
         # collect all tags (returns NULL on error)
         tags_p = Messages._collect_tags(self._msgs)
@@ -144,7 +155,7 @@ class Messages(object):
         self._msgs = None
 
         if tags_p == None:
         self._msgs = None
 
         if tags_p == None:
-            raise NotmuchError(STATUS.NULL_POINTER)
+            raise NullPointerError()
         return Tags(tags_p, self)
 
     def __iter__(self):
         return Tags(tags_p, self)
 
     def __iter__(self):
@@ -161,7 +172,7 @@ class Messages(object):
 
     def __next__(self):
         if not self._msgs:
 
     def __next__(self):
         if not self._msgs:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
 
         if not self._valid(self._msgs):
             self._msgs = None
 
         if not self._valid(self._msgs):
             self._msgs = None
@@ -341,8 +352,8 @@ class Message(Python3StringMixIn):
     def __init__(self, msg_p, parent=None):
         """
         :param msg_p: A pointer to an internal notmuch_message_t
     def __init__(self, msg_p, parent=None):
         """
         :param msg_p: A pointer to an internal notmuch_message_t
-            Structure.  If it is `None`, we will raise an :exc:`NotmuchError`
-            STATUS.NULL_POINTER.
+            Structure.  If it is `None`, we will raise an
+            :exc:`NullPointerError`.
 
         :param parent: A 'parent' object is passed which this message is
               derived from. We save a reference to it, so we can
 
         :param parent: A 'parent' object is passed which this message is
               derived from. We save a reference to it, so we can
@@ -350,7 +361,7 @@ class Message(Python3StringMixIn):
               objects are dead.
         """
         if not msg_p:
               objects are dead.
         """
         if not msg_p:
-            raise NotmuchError(STATUS.NULL_POINTER)
+            raise NullPointerError()
         self._msg = msg_p
         #keep reference to parent, so we keep it alive
         self._parent = parent
         self._msg = msg_p
         #keep reference to parent, so we keep it alive
         self._parent = parent
@@ -359,11 +370,11 @@ class Message(Python3StringMixIn):
         """Returns the message ID
 
         :returns: String with a message ID
         """Returns the message ID
 
         :returns: String with a message ID
-        :exception: :exc:`NotmuchError` STATUS.NOT_INITIALIZED if the message
+        :exception: :exc:`NotInitializedError` if the message
                     is not initialized.
         """
         if not self._msg:
                     is not initialized.
         """
         if not self._msg:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
         return Message._get_message_id(self._msg).decode('utf-8', 'ignore')
 
     def get_thread_id(self):
         return Message._get_message_id(self._msg).decode('utf-8', 'ignore')
 
     def get_thread_id(self):
@@ -376,11 +387,11 @@ class Message(Python3StringMixIn):
         message belongs to a single thread.
 
         :returns: String with a thread ID
         message belongs to a single thread.
 
         :returns: String with a thread ID
-        :exception: :exc:`NotmuchError` STATUS.NOT_INITIALIZED if the message
+        :exception: :exc:`NotInitializedError` if the message
                     is not initialized.
         """
         if not self._msg:
                     is not initialized.
         """
         if not self._msg:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
 
         return Message._get_thread_id(self._msg).decode('utf-8', 'ignore')
 
 
         return Message._get_thread_id(self._msg).decode('utf-8', 'ignore')
 
@@ -399,11 +410,11 @@ class Message(Python3StringMixIn):
             an empty Messages iterator.
 
         :returns: :class:`Messages`.
             an empty Messages iterator.
 
         :returns: :class:`Messages`.
-        :exception: :exc:`NotmuchError` STATUS.NOT_INITIALIZED if the message
+        :exception: :exc:`NotInitializedError` if the message
                     is not initialized.
         """
         if not self._msg:
                     is not initialized.
         """
         if not self._msg:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
 
         msgs_p = Message._get_replies(self._msg)
 
 
         msgs_p = Message._get_replies(self._msg)
 
@@ -421,11 +432,11 @@ class Message(Python3StringMixIn):
 
         :returns: A time_t timestamp.
         :rtype: c_unit64
 
         :returns: A time_t timestamp.
         :rtype: c_unit64
-        :exception: :exc:`NotmuchError` STATUS.NOT_INITIALIZED if the message
+        :exception: :exc:`NotInitializedError` if the message
                     is not initialized.
         """
         if not self._msg:
                     is not initialized.
         """
         if not self._msg:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
         return Message._get_date(self._msg)
 
     def get_header(self, header):
         return Message._get_date(self._msg)
 
     def get_header(self, header):
@@ -441,30 +452,28 @@ class Message(Python3StringMixIn):
                        It is not case-sensitive.
         :type header: str
         :returns: The header value as string
                        It is not case-sensitive.
         :type header: str
         :returns: The header value as string
-        :exception: :exc:`NotmuchError`
-
-                    * STATUS.NOT_INITIALIZED if the message
-                      is not initialized.
-                    * STATUS.NULL_POINTER if any error occured.
+        :raises: :exc:`NotInitializedError` if the message is not
+                 initialized
+        :raises: :exc:`NullPointerError` if any error occured
         """
         if not self._msg:
         """
         if not self._msg:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
 
         #Returns NULL if any error occurs.
         header = Message._get_header(self._msg, _str(header))
         if header == None:
 
         #Returns NULL if any error occurs.
         header = Message._get_header(self._msg, _str(header))
         if header == None:
-            raise NotmuchError(STATUS.NULL_POINTER)
+            raise NullPointerError()
         return header.decode('UTF-8', 'ignore')
 
     def get_filename(self):
         """Returns the file path of the message file
 
         :returns: Absolute file path & name of the message file
         return header.decode('UTF-8', 'ignore')
 
     def get_filename(self):
         """Returns the file path of the message file
 
         :returns: Absolute file path & name of the message file
-        :exception: :exc:`NotmuchError` STATUS.NOT_INITIALIZED if the message
+        :exception: :exc:`NotInitializedError` if the message
               is not initialized.
         """
         if not self._msg:
               is not initialized.
         """
         if not self._msg:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
         return Message._get_filename(self._msg).decode('utf-8', 'ignore')
 
     def get_filenames(self):
         return Message._get_filename(self._msg).decode('utf-8', 'ignore')
 
     def get_filenames(self):
@@ -474,7 +483,7 @@ class Message(Python3StringMixIn):
         messages recorded to have the same Message-ID. These files must
         not necessarily have identical content."""
         if not self._msg:
         messages recorded to have the same Message-ID. These files must
         not necessarily have identical content."""
         if not self._msg:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
 
         files_p = Message._get_filenames(self._msg)
 
 
         files_p = Message._get_filenames(self._msg)
 
@@ -490,11 +499,11 @@ class Message(Python3StringMixIn):
         :param flag: One of the :attr:`Message.FLAG` values (currently only
                      *Message.FLAG.MATCH*
         :returns: An unsigned int (0/1), indicating whether the flag is set.
         :param flag: One of the :attr:`Message.FLAG` values (currently only
                      *Message.FLAG.MATCH*
         :returns: An unsigned int (0/1), indicating whether the flag is set.
-        :exception: :exc:`NotmuchError` STATUS.NOT_INITIALIZED if the message
+        :exception: :exc:`NotInitializedError` if the message
               is not initialized.
         """
         if not self._msg:
               is not initialized.
         """
         if not self._msg:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
         return Message._get_flag(self._msg, flag)
 
     def set_flag(self, flag, value):
         return Message._get_flag(self._msg, flag)
 
     def set_flag(self, flag, value):
@@ -505,29 +514,27 @@ class Message(Python3StringMixIn):
         :param value: A bool indicating whether to set or unset the flag.
 
         :returns: Nothing
         :param value: A bool indicating whether to set or unset the flag.
 
         :returns: Nothing
-        :exception: :exc:`NotmuchError` STATUS.NOT_INITIALIZED if the message
+        :exception: :exc:`NotInitializedError` if the message
               is not initialized.
         """
         if not self._msg:
               is not initialized.
         """
         if not self._msg:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
         self._set_flag(self._msg, flag, value)
 
     def get_tags(self):
         """Returns the message tags
 
         :returns: A :class:`Tags` iterator.
         self._set_flag(self._msg, flag, value)
 
     def get_tags(self):
         """Returns the message tags
 
         :returns: A :class:`Tags` iterator.
-        :exception: :exc:`NotmuchError`
-
-                      * STATUS.NOT_INITIALIZED if the message
-                        is not initialized.
-                      * STATUS.NULL_POINTER, on error
+        :raises: :exc:`NotInitializedError` if the message is not
+                 initialized
+        :raises: :exc:`NullPointerError` if any error occured
         """
         if not self._msg:
         """
         if not self._msg:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
 
         tags_p = Message._get_tags(self._msg)
         if tags_p == None:
 
         tags_p = Message._get_tags(self._msg)
         if tags_p == None:
-            raise NotmuchError(STATUS.NULL_POINTER)
+            raise NullPointerError()
         return Tags(tags_p, self)
 
     _add_tag = nmlib.notmuch_message_add_tag
         return Tags(tags_p, self)
 
     _add_tag = nmlib.notmuch_message_add_tag
@@ -552,21 +559,16 @@ class Message(Python3StringMixIn):
 
         :returns: STATUS.SUCCESS if the tag was successfully added.
                   Raises an exception otherwise.
 
         :returns: STATUS.SUCCESS if the tag was successfully added.
                   Raises an exception otherwise.
-        :exception: :exc:`NotmuchError`. They have the following meaning:
-
-                  STATUS.NULL_POINTER
-                    The 'tag' argument is NULL
-                  STATUS.TAG_TOO_LONG
-                    The length of 'tag' is too long
-                    (exceeds Message.NOTMUCH_TAG_MAX)
-                  STATUS.READ_ONLY_DATABASE
-                    Database was opened in read-only mode so message cannot be
-                    modified.
-                  STATUS.NOT_INITIALIZED
-                     The message has not been initialized.
-       """
+        :raises: :exc:`NullPointerError` if the `tag` argument is NULL
+        :raises: :exc:`TagTooLongError` if the length of `tag` exceeds
+                 Message.NOTMUCH_TAG_MAX)
+        :raises: :exc:`ReadOnlyDatabaseError` if the database was opened
+                 in read-only mode so message cannot be modified
+        :raises: :exc:`NotInitializedError` if message has not been
+                 initialized
+        """
         if not self._msg:
         if not self._msg:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
 
         status = self._add_tag(self._msg, _str(tag))
 
 
         status = self._add_tag(self._msg, _str(tag))
 
@@ -600,21 +602,16 @@ class Message(Python3StringMixIn):
         :returns: STATUS.SUCCESS if the tag was successfully removed or if
                   the message had no such tag.
                   Raises an exception otherwise.
         :returns: STATUS.SUCCESS if the tag was successfully removed or if
                   the message had no such tag.
                   Raises an exception otherwise.
-        :exception: :exc:`NotmuchError`. They have the following meaning:
-
-                   STATUS.NULL_POINTER
-                     The 'tag' argument is NULL
-                   STATUS.TAG_TOO_LONG
-                     The length of 'tag' is too long
-                     (exceeds NOTMUCH_TAG_MAX)
-                   STATUS.READ_ONLY_DATABASE
-                     Database was opened in read-only mode so message cannot
-                     be modified.
-                   STATUS.NOT_INITIALIZED
-                     The message has not been initialized.
+        :raises: :exc:`NullPointerError` if the `tag` argument is NULL
+        :raises: :exc:`TagTooLongError` if the length of `tag` exceeds
+                 Message.NOTMUCH_TAG_MAX)
+        :raises: :exc:`ReadOnlyDatabaseError` if the database was opened
+                 in read-only mode so message cannot be modified
+        :raises: :exc:`NotInitializedError` if message has not been
+                 initialized
         """
         if not self._msg:
         """
         if not self._msg:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
 
         status = self._remove_tag(self._msg, _str(tag))
         # bail out on error
 
         status = self._remove_tag(self._msg, _str(tag))
         # bail out on error
@@ -646,16 +643,13 @@ class Message(Python3StringMixIn):
 
         :returns: STATUS.SUCCESS if the tags were successfully removed.
                   Raises an exception otherwise.
 
         :returns: STATUS.SUCCESS if the tags were successfully removed.
                   Raises an exception otherwise.
-        :exception: :exc:`NotmuchError`. They have the following meaning:
-
-                   STATUS.READ_ONLY_DATABASE
-                     Database was opened in read-only mode so message cannot
-                     be modified.
-                   STATUS.NOT_INITIALIZED
-                     The message has not been initialized.
+        :raises: :exc:`ReadOnlyDatabaseError` if the database was opened
+                 in read-only mode so message cannot be modified
+        :raises: :exc:`NotInitializedError` if message has not been
+                 initialized
         """
         if not self._msg:
         """
         if not self._msg:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
 
         status = self._remove_all_tags(self._msg)
 
 
         status = self._remove_all_tags(self._msg)
 
@@ -704,16 +698,13 @@ class Message(Python3StringMixIn):
 
         :returns: STATUS.SUCCESS if the message was successfully frozen.
                   Raises an exception otherwise.
 
         :returns: STATUS.SUCCESS if the message was successfully frozen.
                   Raises an exception otherwise.
-        :exception: :exc:`NotmuchError`. They have the following meaning:
-
-                   STATUS.READ_ONLY_DATABASE
-                     Database was opened in read-only mode so message cannot
-                     be modified.
-                   STATUS.NOT_INITIALIZED
-                     The message has not been initialized.
+        :raises: :exc:`ReadOnlyDatabaseError` if the database was opened
+                 in read-only mode so message cannot be modified
+        :raises: :exc:`NotInitializedError` if message has not been
+                 initialized
         """
         if not self._msg:
         """
         if not self._msg:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
 
         status = self._freeze(self._msg)
 
 
         status = self._freeze(self._msg)
 
@@ -742,17 +733,15 @@ class Message(Python3StringMixIn):
 
         :returns: STATUS.SUCCESS if the message was successfully frozen.
                   Raises an exception otherwise.
 
         :returns: STATUS.SUCCESS if the message was successfully frozen.
                   Raises an exception otherwise.
-        :exception: :exc:`NotmuchError`. They have the following meaning:
-
-                   STATUS.UNBALANCED_FREEZE_THAW
-                     An attempt was made to thaw an unfrozen message.
-                     That is, there have been an unbalanced number of calls
-                     to :meth:`freeze` and :meth:`thaw`.
-                   STATUS.NOT_INITIALIZED
-                     The message has not been initialized.
+        :raises: :exc:`UnbalancedFreezeThawError` if an attempt was made
+                 to thaw an unfrozen message. That is, there have been
+                 an unbalanced number of calls to :meth:`freeze` and
+                 :meth:`thaw`.
+        :raises: :exc:`NotInitializedError` if message has not been
+                 initialized
         """
         if not self._msg:
         """
         if not self._msg:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
 
         status = self._thaw(self._msg)
 
 
         status = self._thaw(self._msg)
 
@@ -788,7 +777,7 @@ class Message(Python3StringMixIn):
         :returns: a :class:`STATUS` value. In short, you want to see
             notmuch.STATUS.SUCCESS here. See there for details."""
         if not self._msg:
         :returns: a :class:`STATUS` value. In short, you want to see
             notmuch.STATUS.SUCCESS here. See there for details."""
         if not self._msg:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
         return Message._tags_to_maildir_flags(self._msg)
 
     def maildir_flags_to_tags(self):
         return Message._tags_to_maildir_flags(self._msg)
 
     def maildir_flags_to_tags(self):
@@ -815,7 +804,7 @@ class Message(Python3StringMixIn):
         :returns: a :class:`STATUS`. In short, you want to see
             notmuch.STATUS.SUCCESS here. See there for details."""
         if not self._msg:
         :returns: a :class:`STATUS`. In short, you want to see
             notmuch.STATUS.SUCCESS here. See there for details."""
         if not self._msg:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
         return Message._tags_to_maildir_flags(self._msg)
 
     def __repr__(self):
         return Message._tags_to_maildir_flags(self._msg)
 
     def __repr__(self):
index d0f7bb402f2c4ddaa2dda4533fd07ba2428bf5fb..526e51cd3c2697af207d5ff1c7b5ec293cd5b85d 100644 (file)
@@ -17,7 +17,13 @@ along with notmuch.  If not, see <http://www.gnu.org/licenses/>.
 Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>'
 """
 from ctypes import c_char_p
 Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>'
 """
 from ctypes import c_char_p
-from notmuch.globals import nmlib, STATUS, NotmuchError, NotmuchTagsP, Python3StringMixIn
+from notmuch.globals import (
+    nmlib,
+    Python3StringMixIn,
+    NullPointerError,
+    NotInitializedError,
+    NotmuchTagsP,
+)
 
 
 class Tags(Python3StringMixIn):
 
 
 class Tags(Python3StringMixIn):
@@ -29,9 +35,9 @@ class Tags(Python3StringMixIn):
     Do note that the underlying library only provides a one-time
     iterator (it cannot reset the iterator to the start). Thus iterating
     over the function will "exhaust" the list of tags, and a subsequent
     Do note that the underlying library only provides a one-time
     iterator (it cannot reset the iterator to the start). Thus iterating
     over the function will "exhaust" the list of tags, and a subsequent
-    iteration attempt will raise a :exc:`NotmuchError`
-    STATUS.NOT_INITIALIZED. Also note, that any function that uses
-    iteration (nearly all) will also exhaust the tags. So both::
+    iteration attempt will raise a :exc:`NotInitializedError`.
+    Also note, that any function that uses iteration (nearly all) will
+    also exhaust the tags. So both::
 
       for tag in tags: print tag
 
 
       for tag in tags: print tag
 
@@ -60,8 +66,8 @@ class Tags(Python3StringMixIn):
              will almost never instantiate a :class:`Tags` object
              herself. They are usually handed back as a result,
              e.g. in :meth:`Database.get_all_tags`.  *tags_p* must be
              will almost never instantiate a :class:`Tags` object
              herself. They are usually handed back as a result,
              e.g. in :meth:`Database.get_all_tags`.  *tags_p* must be
-             valid, we will raise an :exc:`NotmuchError`
-             (STATUS.NULL_POINTER) if it is `None`.
+             valid, we will raise an :exc:`NullPointerError` if it is
+             `None`.
         :type tags_p: :class:`ctypes.c_void_p`
         :param parent: The parent object (ie :class:`Database` or
              :class:`Message` these tags are derived from, and saves a
         :type tags_p: :class:`ctypes.c_void_p`
         :param parent: The parent object (ie :class:`Database` or
              :class:`Message` these tags are derived from, and saves a
@@ -71,7 +77,7 @@ class Tags(Python3StringMixIn):
                cache the tags in the Python object(?)
         """
         if not tags_p:
                cache the tags in the Python object(?)
         """
         if not tags_p:
-            raise NotmuchError(STATUS.NULL_POINTER)
+            raise NullPointerError()
 
         self._tags = tags_p
         #save reference to parent object so we keep it alive
 
         self._tags = tags_p
         #save reference to parent object so we keep it alive
@@ -91,7 +97,7 @@ class Tags(Python3StringMixIn):
 
     def __next__(self):
         if not self._tags:
 
     def __next__(self):
         if not self._tags:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
         if not self._valid(self._tags):
             self._tags = None
             raise StopIteration
         if not self._valid(self._tags):
             self._tags = None
             raise StopIteration
@@ -118,8 +124,8 @@ class Tags(Python3StringMixIn):
 
             As this iterates over the tags, we will not be able to iterate over
             them again (as in retrieve them)! If the tags have been exhausted
 
             As this iterates over the tags, we will not be able to iterate over
             them again (as in retrieve them)! If the tags have been exhausted
-            already, this will raise a :exc:`NotmuchError`
-            STATUS.NOT_INITIALIZED on subsequent attempts.
+            already, this will raise a :exc:`NotInitializedError`on subsequent
+            attempts.
         """
         return " ".join(self)
 
         """
         return " ".join(self)
 
index c2347fe7d856e7cf9f35598c7ebb4439bfae0f74..5c580288e505c0a39672ea89bf5caa1aeb2d7aff 100644 (file)
@@ -18,9 +18,16 @@ Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>'
 """
 
 from ctypes import c_char_p, c_long, c_int
 """
 
 from ctypes import c_char_p, c_long, c_int
-from notmuch.globals import (nmlib, STATUS,
-    NotmuchError, NotmuchThreadP, NotmuchThreadsP, NotmuchMessagesP,
-    NotmuchTagsP, Python3StringMixIn)
+from notmuch.globals import (
+    nmlib,
+    Python3StringMixIn,
+    NullPointerError,
+    NotInitializedError,
+    NotmuchThreadP,
+    NotmuchThreadsP,
+    NotmuchMessagesP,
+    NotmuchTagsP,
+)
 from notmuch.message import Messages
 from notmuch.tag import Tags
 from datetime import date
 from notmuch.message import Messages
 from notmuch.tag import Tags
 from datetime import date
@@ -35,7 +42,7 @@ class Threads(Python3StringMixIn):
     library only provides a one-time iterator (it cannot reset the
     iterator to the start). Thus iterating over the function will
     "exhaust" the list of threads, and a subsequent iteration attempt
     library only provides a one-time iterator (it cannot reset the
     iterator to the start). Thus iterating over the function will
     "exhaust" the list of threads, and a subsequent iteration attempt
-    will raise a :exc:`NotmuchError` STATUS.NOT_INITIALIZED. Also
+    will raise a :exc:`NotInitializedError`. Also
     note, that any function that uses iteration will also
     exhaust the messages. So both::
 
     note, that any function that uses iteration will also
     exhaust the messages. So both::
 
@@ -87,8 +94,8 @@ class Threads(Python3StringMixIn):
              will almost never instantiate a :class:`Threads` object
              herself. They are usually handed back as a result,
              e.g. in :meth:`Query.search_threads`.  *threads_p* must be
              will almost never instantiate a :class:`Threads` object
              herself. They are usually handed back as a result,
              e.g. in :meth:`Query.search_threads`.  *threads_p* must be
-             valid, we will raise an :exc:`NotmuchError`
-             (STATUS.NULL_POINTER) if it is `None`.
+             valid, we will raise an :exc:`NullPointerError` if it is
+             `None`.
         :type threads_p: :class:`ctypes.c_void_p`
         :param parent: The parent object
              (ie :class:`Query`) these tags are derived from. It saves
         :type threads_p: :class:`ctypes.c_void_p`
         :param parent: The parent object
              (ie :class:`Query`) these tags are derived from. It saves
@@ -98,7 +105,7 @@ class Threads(Python3StringMixIn):
                the Python object.(?)
         """
         if not threads_p:
                the Python object.(?)
         """
         if not threads_p:
-            raise NotmuchError(STATUS.NULL_POINTER)
+            raise NullPointerError()
 
         self._threads = threads_p
         #store parent, so we keep them alive as long as self  is alive
 
         self._threads = threads_p
         #store parent, so we keep them alive as long as self  is alive
@@ -118,7 +125,7 @@ class Threads(Python3StringMixIn):
 
     def __next__(self):
         if not self._threads:
 
     def __next__(self):
         if not self._threads:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
 
         if not self._valid(self._threads):
             self._threads = None
 
         if not self._valid(self._threads):
             self._threads = None
@@ -138,11 +145,11 @@ class Threads(Python3StringMixIn):
                  #THIS FAILS
                  threads = Database().create_query('').search_threads()
                  if len(threads) > 0:              #this 'exhausts' threads
                  #THIS FAILS
                  threads = Database().create_query('').search_threads()
                  if len(threads) > 0:              #this 'exhausts' threads
-                     # next line raises NotmuchError(STATUS.NOT_INITIALIZED)!!!
+                     # next line raises :exc:`NotInitializedError`!!!
                      for thread in threads: print thread
         """
         if not self._threads:
                      for thread in threads: print thread
         """
         if not self._threads:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
 
         i = 0
         # returns 'bool'. On out-of-memory it returns None
 
         i = 0
         # returns 'bool'. On out-of-memory it returns None
@@ -220,8 +227,8 @@ class Thread(object):
             will almost never instantiate a :class:`Thread` object
             herself. They are usually handed back as a result,
             e.g. when iterating through :class:`Threads`. *thread_p*
             will almost never instantiate a :class:`Thread` object
             herself. They are usually handed back as a result,
             e.g. when iterating through :class:`Threads`. *thread_p*
-            must be valid, we will raise an :exc:`NotmuchError`
-            (STATUS.NULL_POINTER) if it is `None`.
+            must be valid, we will raise an :exc:`NullPointerError`
+            if it is `None`.
 
         :param parent: A 'parent' object is passed which this message is
               derived from. We save a reference to it, so we can
 
         :param parent: A 'parent' object is passed which this message is
               derived from. We save a reference to it, so we can
@@ -229,7 +236,7 @@ class Thread(object):
               objects are dead.
         """
         if not thread_p:
               objects are dead.
         """
         if not thread_p:
-            raise NotmuchError(STATUS.NULL_POINTER)
+            raise NullPointerError()
         self._thread = thread_p
         #keep reference to parent, so we keep it alive
         self._parent = parent
         self._thread = thread_p
         #keep reference to parent, so we keep it alive
         self._parent = parent
@@ -241,11 +248,11 @@ class Thread(object):
         for as long as the thread is valid.
 
         :returns: String with a message ID
         for as long as the thread is valid.
 
         :returns: String with a message ID
-        :exception: :exc:`NotmuchError` STATUS.NOT_INITIALIZED if the thread
+        :exception: :exc:`NotInitializedError` if the thread
                     is not initialized.
         """
         if not self._thread:
                     is not initialized.
         """
         if not self._thread:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
         return Thread._get_thread_id(self._thread).decode('utf-8', 'ignore')
 
     _get_total_messages = nmlib.notmuch_thread_get_total_messages
         return Thread._get_thread_id(self._thread).decode('utf-8', 'ignore')
 
     _get_total_messages = nmlib.notmuch_thread_get_total_messages
@@ -258,11 +265,11 @@ class Thread(object):
         :returns: The number of all messages in the database
                   belonging to this thread. Contrast with
                   :meth:`get_matched_messages`.
         :returns: The number of all messages in the database
                   belonging to this thread. Contrast with
                   :meth:`get_matched_messages`.
-        :exception: :exc:`NotmuchError` STATUS.NOT_INITIALIZED if the thread
+        :exception: :exc:`NotInitializedError` if the thread
                     is not initialized.
         """
         if not self._thread:
                     is not initialized.
         """
         if not self._thread:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
         return self._get_total_messages(self._thread)
 
     def get_toplevel_messages(self):
         return self._get_total_messages(self._thread)
 
     def get_toplevel_messages(self):
@@ -279,18 +286,16 @@ class Thread(object):
            messages, etc.).
 
         :returns: :class:`Messages`
            messages, etc.).
 
         :returns: :class:`Messages`
-        :exception: :exc:`NotmuchError`
-
-                      * STATUS.NOT_INITIALIZED if query is not inited
-                      * STATUS.NULL_POINTER if search_messages failed
+        :raises: :exc:`NotInitializedError` if query is not initialized
+        :raises: :exc:`NullPointerError` if search_messages failed
         """
         if not self._thread:
         """
         if not self._thread:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
 
         msgs_p = Thread._get_toplevel_messages(self._thread)
 
         if not msgs_p:
 
         msgs_p = Thread._get_toplevel_messages(self._thread)
 
         if not msgs_p:
-            raise NotmuchError(STATUS.NULL_POINTER)
+            raise NullPointerError()
 
         return Messages(msgs_p, self)
 
 
         return Messages(msgs_p, self)
 
@@ -304,11 +309,11 @@ class Thread(object):
         :returns: The number of all messages belonging to this thread that
                   matched the :class:`Query`from which this thread was created.
                   Contrast with :meth:`get_total_messages`.
         :returns: The number of all messages belonging to this thread that
                   matched the :class:`Query`from which this thread was created.
                   Contrast with :meth:`get_total_messages`.
-        :exception: :exc:`NotmuchError` STATUS.NOT_INITIALIZED if the thread
+        :exception: :exc:`NotInitializedError` if the thread
                     is not initialized.
         """
         if not self._thread:
                     is not initialized.
         """
         if not self._thread:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
         return self._get_matched_messages(self._thread)
 
     def get_authors(self):
         return self._get_matched_messages(self._thread)
 
     def get_authors(self):
@@ -322,7 +327,7 @@ class Thread(object):
         as long as this Thread() is not deleted.
         """
         if not self._thread:
         as long as this Thread() is not deleted.
         """
         if not self._thread:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
         authors = Thread._get_authors(self._thread)
         if not authors:
             return None
         authors = Thread._get_authors(self._thread)
         if not authors:
             return None
@@ -335,7 +340,7 @@ class Thread(object):
         as long as this Thread() is not deleted.
         """
         if not self._thread:
         as long as this Thread() is not deleted.
         """
         if not self._thread:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
         subject = Thread._get_subject(self._thread)
         if not subject:
             return None
         subject = Thread._get_subject(self._thread)
         if not subject:
             return None
@@ -346,11 +351,11 @@ class Thread(object):
 
         :returns: A time_t timestamp.
         :rtype: c_unit64
 
         :returns: A time_t timestamp.
         :rtype: c_unit64
-        :exception: :exc:`NotmuchError` STATUS.NOT_INITIALIZED if the message
+        :exception: :exc:`NotInitializedError` if the message
                     is not initialized.
         """
         if not self._thread:
                     is not initialized.
         """
         if not self._thread:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
         return Thread._get_newest_date(self._thread)
 
     def get_oldest_date(self):
         return Thread._get_newest_date(self._thread)
 
     def get_oldest_date(self):
@@ -358,11 +363,11 @@ class Thread(object):
 
         :returns: A time_t timestamp.
         :rtype: c_unit64
 
         :returns: A time_t timestamp.
         :rtype: c_unit64
-        :exception: :exc:`NotmuchError` STATUS.NOT_INITIALIZED if the message
+        :exception: :exc:`NotInitializedError` if the message
                     is not initialized.
         """
         if not self._thread:
                     is not initialized.
         """
         if not self._thread:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
         return Thread._get_oldest_date(self._thread)
 
     def get_tags(self):
         return Thread._get_oldest_date(self._thread)
 
     def get_tags(self):
@@ -378,18 +383,15 @@ class Thread(object):
         query from which it derived is explicitely deleted).
 
         :returns: A :class:`Tags` iterator.
         query from which it derived is explicitely deleted).
 
         :returns: A :class:`Tags` iterator.
-        :exception: :exc:`NotmuchError`
-
-                      * STATUS.NOT_INITIALIZED if the thread
-                        is not initialized.
-                      * STATUS.NULL_POINTER, on error
+        :raises: :exc:`NotInitializedError` if query is not initialized
+        :raises: :exc:`NullPointerError` if search_messages failed
         """
         if not self._thread:
         """
         if not self._thread:
-            raise NotmuchError(STATUS.NOT_INITIALIZED)
+            raise NotInitializedError()
 
         tags_p = Thread._get_tags(self._thread)
         if tags_p == None:
 
         tags_p = Thread._get_tags(self._thread)
         if tags_p == None:
-            raise NotmuchError(STATUS.NULL_POINTER)
+            raise NullPointerError()
         return Tags(tags_p, self)
 
     def __unicode__(self):
         return Tags(tags_p, self)
 
     def __unicode__(self):