--- /dev/null
+Return-Path: <teythoon@jade-hamburg.de>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+ by olra.theworths.org (Postfix) with ESMTP id B977F431FD0\r
+ for <notmuch@notmuchmail.org>; Sun, 25 Sep 2011 18:07:10 -0700 (PDT)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: 0\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[none]\r
+ autolearn=disabled\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+ by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+ with ESMTP id O7Phf2ye+DsR for <notmuch@notmuchmail.org>;\r
+ Sun, 25 Sep 2011 18:07:08 -0700 (PDT)\r
+Received: from mail.cryptobitch.de (cryptobitch.de [88.198.7.68])\r
+ (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits))\r
+ (No client certificate requested)\r
+ by olra.theworths.org (Postfix) with ESMTPS id E9DD6431FB6\r
+ for <notmuch@notmuchmail.org>; Sun, 25 Sep 2011 18:07:07 -0700 (PDT)\r
+Received: from mail.jade-hamburg.de (unknown [85.183.11.228])\r
+ (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits))\r
+ (No client certificate requested)\r
+ by mail.cryptobitch.de (Postfix) with ESMTPSA id B529F505B24\r
+ for <notmuch@notmuchmail.org>; Mon, 26 Sep 2011 03:07:06 +0200 (CEST)\r
+Received: by mail.jade-hamburg.de (Postfix, from userid 401)\r
+ id 35F2BDF29F; Mon, 26 Sep 2011 03:07:06 +0200 (CEST)\r
+Received: from thinkbox.jade-hamburg.de (unknown [10.1.1.109])\r
+ (using TLSv1 with cipher AES256-SHA (256/256 bits))\r
+ (No client certificate requested) (Authenticated sender: teythoon)\r
+ by mail.jade-hamburg.de (Postfix) with ESMTPSA id 8C7B0DF2A5;\r
+ Mon, 26 Sep 2011 03:06:14 +0200 (CEST)\r
+Received: from teythoon by thinkbox.jade-hamburg.de with local (Exim 4.76)\r
+ (envelope-from <teythoon@thinkbox.jade-hamburg.de>)\r
+ id 1R7ze5-0007OY-R8; Mon, 26 Sep 2011 03:06:09 +0200\r
+From: Justus Winter <4winter@informatik.uni-hamburg.de>\r
+To: notmuch@notmuchmail.org\r
+Subject: [PATCH 8/9] python: use the new exception classes and update the\r
+ documentation\r
+Date: Mon, 26 Sep 2011 03:05:36 +0200\r
+Message-Id:\r
+ <1316999137-28257-8-git-send-email-4winter@informatik.uni-hamburg.de>\r
+X-Mailer: git-send-email 1.7.6.3\r
+In-Reply-To:\r
+ <1316999137-28257-1-git-send-email-4winter@informatik.uni-hamburg.de>\r
+References:\r
+ <1316999137-28257-1-git-send-email-4winter@informatik.uni-hamburg.de>\r
+X-Mailman-Approved-At: Mon, 26 Sep 2011 09:17:56 -0700\r
+Cc: Justus Winter <4winter@informatik.uni-hamburg.de>\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+ <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Mon, 26 Sep 2011 01:07:10 -0000\r
+\r
+Signed-off-by: Justus Winter <4winter@informatik.uni-hamburg.de>\r
+---\r
+ bindings/python/notmuch/database.py | 138 +++++++++++++++++++++--------------\r
+ bindings/python/notmuch/filename.py | 9 +-\r
+ bindings/python/notmuch/message.py | 79 ++++++++++----------\r
+ bindings/python/notmuch/tag.py | 10 ++-\r
+ bindings/python/notmuch/thread.py | 47 ++++++------\r
+ 5 files changed, 158 insertions(+), 125 deletions(-)\r
+\r
+diff --git a/bindings/python/notmuch/database.py b/bindings/python/notmuch/database.py\r
+index edde70e..8df7c2f 100644\r
+--- a/bindings/python/notmuch/database.py\r
++++ b/bindings/python/notmuch/database.py\r
+@@ -19,7 +19,9 @@ Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>'\r
+ \r
+ import os\r
+ from ctypes import c_int, c_char_p, c_void_p, c_uint, c_long, byref\r
+-from notmuch.globals import nmlib, STATUS, NotmuchError, Enum, _str\r
++from notmuch.globals import nmlib, STATUS, NotmuchError, Enum, _str, \\r
++ NotInitializedError, FileError, \\r
++ NullPointerError\r
+ from notmuch.thread import Threads\r
+ from notmuch.message import Messages, Message\r
+ from notmuch.tag import Tags\r
+@@ -106,9 +108,9 @@ class Database(object):\r
+ self.create(path)\r
+ \r
+ def _assert_db_is_initialized(self):\r
+- """Raises a NotmuchError in case self._db is still None"""\r
++ """Raises a :exc:`NotInitializedError` in case self._db is still None"""\r
+ if self._db is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ \r
+ def create(self, path):\r
+ """Creates a new notmuch database\r
+@@ -160,7 +162,12 @@ class Database(object):\r
+ def get_path(self):\r
+ """Returns the file path of an open database\r
+ \r
+- Wraps *notmuch_database_get_path*."""\r
++ Wraps *notmuch_database_get_path*.\r
++\r
++ :returns: The path to the database as string\r
++ :exception: :exc:`NotInitializedError` if\r
++ the database was not intitialized.\r
++ """\r
+ self._assert_db_is_initialized()\r
+ \r
+ return Database._get_path(self._db).decode('utf-8')\r
+@@ -169,7 +176,7 @@ class Database(object):\r
+ """Returns the database format version\r
+ \r
+ :returns: The database version as positive integer\r
+- :exception: :exc:`NotmuchError` with STATUS.NOT_INITIALIZED if\r
++ :exception: :exc:`NotInitializedError` if\r
+ the database was not intitialized.\r
+ """\r
+ self._assert_db_is_initialized()\r
+@@ -185,7 +192,7 @@ class Database(object):\r
+ etc.) will work unless :meth:`upgrade` is called successfully first.\r
+ \r
+ :returns: `True` or `False`\r
+- :exception: :exc:`NotmuchError` with STATUS.NOT_INITIALIZED if\r
++ :exception: :exc:`NotInitializedError` if\r
+ the database was not intitialized.\r
+ """\r
+ self._assert_db_is_initialized()\r
+@@ -206,6 +213,9 @@ class Database(object):\r
+ indicating the progress made so far in the upgrade process.\r
+ \r
+ :TODO: catch exceptions, document return values and etc...\r
++\r
++ :exception: :exc:`NotInitializedError` if\r
++ the database was not intitialized.\r
+ """\r
+ self._assert_db_is_initialized()\r
+ \r
+@@ -225,15 +235,14 @@ class Database(object):\r
+ of database (see :meth:`get_path`), or else should be an absolute path\r
+ with initial components that match the path of 'database'.\r
+ :returns: :class:`Directory` or raises an exception.\r
+- :exception: :exc:`NotmuchError`\r
++ :exception: :exc:`NotInitializedError` or :exc:`FileError`\r
+ \r
+- STATUS.NOT_INITIALIZED\r
++ :exc:`NotInitializedError`\r
+ If the database was not intitialized.\r
+ \r
+- STATUS.FILE_ERROR\r
++ :exc:`FileError`\r
+ If path is not relative database or absolute with initial\r
+ components same as database.\r
+-\r
+ """\r
+ self._assert_db_is_initialized()\r
+ \r
+@@ -242,9 +251,8 @@ class Database(object):\r
+ # we got an absolute path\r
+ if not path.startswith(self.get_path()):\r
+ # but its initial components are not equal to the db path\r
+- raise NotmuchError(message="Database().get_directory() called "\r
+- "with a wrong absolute path.",\r
+- status=STATUS.FILE_ERROR)\r
++ raise FileError("Database().get_directory() called "\r
++ "with a wrong absolute path.")\r
+ abs_dirpath = path\r
+ else:\r
+ #we got a relative path, make it absolute\r
+@@ -293,16 +301,16 @@ class Database(object):\r
+ :exception: Raises a :exc:`NotmuchError` with the following meaning.\r
+ If such an exception occurs, nothing was added to the database.\r
+ \r
+- STATUS.FILE_ERROR\r
++ :exc:`FileError`\r
+ An error occurred trying to open the file, (such as\r
+ permission denied, or file not found, etc.).\r
+- STATUS.FILE_NOT_EMAIL\r
++ :exc:`FileNotEmail`\r
+ The contents of filename don't look like an email\r
+ message.\r
+- STATUS.READ_ONLY_DATABASE\r
++ :exc:`ReadOnlyDatabaseError`\r
+ Database was opened in read-only mode so no message can\r
+ be added.\r
+- STATUS.NOT_INITIALIZED\r
++ :exc:`NotInitializedError`\r
+ The database has not been initialized.\r
+ """\r
+ self._assert_db_is_initialized()\r
+@@ -313,7 +321,7 @@ class Database(object):\r
+ byref(msg_p))\r
+ \r
+ if not status in [STATUS.SUCCESS, STATUS.DUPLICATE_MESSAGE_ID]:\r
+- raise NotmuchError(status=status)\r
++ raise NotmuchError.decode(status)\r
+ \r
+ #construct Message() and return\r
+ msg = Message(msg_p, self)\r
+@@ -345,10 +353,10 @@ class Database(object):\r
+ If such an exception occurs, nothing was removed from the\r
+ database.\r
+ \r
+- STATUS.READ_ONLY_DATABASE\r
++ :exc:`ReadOnlyDatabaseError`\r
+ Database was opened in read-only mode so no message can be\r
+ removed.\r
+- STATUS.NOT_INITIALIZED\r
++ :exc:`NotInitializedError`\r
+ The database has not been initialized.\r
+ """\r
+ self._assert_db_is_initialized()\r
+@@ -371,7 +379,7 @@ class Database(object):\r
+ another program in the meantime. A return value of\r
+ `None` is therefore no guarantee that the message\r
+ does not exist.\r
+- :exception: :exc:`NotmuchError` with STATUS.NOT_INITIALIZED if\r
++ :exception: :exc:`NotInitializedError` if\r
+ the database was not intitialized.\r
+ """\r
+ self._assert_db_is_initialized()\r
+@@ -383,13 +391,13 @@ class Database(object):\r
+ """Returns :class:`Tags` with a list of all tags found in the database\r
+ \r
+ :returns: :class:`Tags`\r
+- :execption: :exc:`NotmuchError` with STATUS.NULL_POINTER on error\r
++ :execption: :exc:`NullPointerError` on error\r
+ """\r
+ self._assert_db_is_initialized()\r
+ \r
+ tags_p = Database._get_all_tags(self._db)\r
+ if tags_p == None:\r
+- raise NotmuchError(status=STATUS.NULL_POINTER)\r
++ raise NullPointerError()\r
+ return Tags(tags_p, self)\r
+ \r
+ def create_query(self, querystring):\r
+@@ -409,6 +417,9 @@ class Database(object):\r
+ q = Query(db,'from:"Biene Maja"')\r
+ \r
+ This function is a python extension and not in the underlying C API.\r
++\r
++ :exception: :exc:`NotInitializedError` if\r
++ the database was not intitialized.\r
+ """\r
+ self._assert_db_is_initialized()\r
+ \r
+@@ -425,7 +436,8 @@ class Database(object):\r
+ def _get_user_default_db(self):\r
+ """ Reads a user's notmuch config and returns his db location\r
+ \r
+- Throws a NotmuchError if it cannot find it"""\r
++ :exception: :exc:`NotMuchError` if it cannot find it\r
++ """\r
+ from ConfigParser import SafeConfigParser\r
+ config = SafeConfigParser()\r
+ conf_f = os.getenv('NOTMUCH_CONFIG',\r
+@@ -507,20 +519,20 @@ class Query(object):\r
+ :param querystr: The query string\r
+ :type querystr: utf-8 encoded str or unicode\r
+ :returns: Nothing\r
+- :exception: :exc:`NotmuchError`\r
++ :exception: :exc:`NotInitializedError` or :exc:`NullPointerError`\r
+ \r
+- * STATUS.NOT_INITIALIZED if db is not inited\r
+- * STATUS.NULL_POINTER if the query creation failed\r
++ :exc:`NotInitializedError` if db is not initialized\r
++ :exc:`NullPointerError` if the query creation failed\r
+ (too little memory)\r
+ """\r
+ if db.db_p is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ # create reference to parent db to keep it alive\r
+ self._db = db\r
+ # create query, return None if too little mem available\r
+ query_p = Query._create(db.db_p, _str(querystr))\r
+ if query_p is None:\r
+- raise NotmuchError(status=STATUS.NULL_POINTER)\r
++ raise NullPointerError()\r
+ self._query = query_p\r
+ \r
+ def set_sort(self, sort):\r
+@@ -530,11 +542,11 @@ class Query(object):\r
+ \r
+ :param sort: Sort order (see :attr:`Query.SORT`)\r
+ :returns: Nothing\r
+- :exception: :exc:`NotmuchError` STATUS.NOT_INITIALIZED if query has not\r
++ :exception: :exc:`NotInitializedError` if query has not\r
+ been initialized.\r
+ """\r
+ if self._query is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ \r
+ self.sort = sort\r
+ nmlib.notmuch_query_set_sort(self._query, sort)\r
+@@ -554,18 +566,18 @@ class Query(object):\r
+ *notmuch_query_search_threads* function.\r
+ \r
+ :returns: :class:`Threads`\r
+- :exception: :exc:`NotmuchError`\r
++ :exception: :exc:`NotInitializedError` or :exc:`NullPointerError`\r
+ \r
+- * STATUS.NOT_INITIALIZED if query is not inited\r
+- * STATUS.NULL_POINTER if search_threads failed\r
++ :exc:`NotInitializedError` if query is not initialized\r
++ :exc:`NullPointerError` if the search_threads failed\r
+ """\r
+ if self._query is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ \r
+ threads_p = Query._search_threads(self._query)\r
+ \r
+ if threads_p is None:\r
+- raise NotmuchError(status=STATUS.NULL_POINTER)\r
++ raise NullPointerError()\r
+ \r
+ return Threads(threads_p, self)\r
+ \r
+@@ -577,18 +589,18 @@ class Query(object):\r
+ *notmuch_query_search_messages* function.\r
+ \r
+ :returns: :class:`Messages`\r
+- :exception: :exc:`NotmuchError`\r
++ :exception: :exc:`NotInitializedError` or :exc:`NullPointerError`\r
+ \r
+- * STATUS.NOT_INITIALIZED if query is not inited\r
+- * STATUS.NULL_POINTER if search_messages failed\r
++ :exc:`NotInitializedError` if query is not initialized\r
++ :exc:`NullPointerError` if the search_messages failed\r
+ """\r
+ if self._query is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ \r
+ msgs_p = Query._search_messages(self._query)\r
+ \r
+ if msgs_p is None:\r
+- raise NotmuchError(status=STATUS.NULL_POINTER)\r
++ raise NullPointerError()\r
+ \r
+ return Messages(msgs_p, self)\r
+ \r
+@@ -603,12 +615,12 @@ class Query(object):\r
+ *notmuch_query_count_messages* function.\r
+ \r
+ :returns: :class:`Messages`\r
+- :exception: :exc:`NotmuchError`\r
++ :exception: :exc:`NotInitializedError`\r
+ \r
+- * STATUS.NOT_INITIALIZED if query is not inited\r
++ :exc:`NotInitializedError` if query is not initialized\r
+ """\r
+ if self._query is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ \r
+ return Query._count_messages(self._query)\r
+ \r
+@@ -651,7 +663,7 @@ class Directory(object):\r
+ def _assert_dir_is_initialized(self):\r
+ """Raises a NotmuchError(status=STATUS.NOT_INITIALIZED) if dir_p is None"""\r
+ if self._dir_p is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ \r
+ def __init__(self, path, dir_p, parent):\r
+ """\r
+@@ -693,14 +705,15 @@ class Directory(object):\r
+ \r
+ :param mtime: A (time_t) timestamp\r
+ :returns: Nothing on success, raising an exception on failure.\r
+- :exception: :exc:`NotmuchError`:\r
++ :exception: :exc:`NotInitializedError`, :exc:`XapianError` or\r
++ :exc:`ReadOnlyDatabaseError`\r
+ \r
+- STATUS.XAPIAN_EXCEPTION\r
++ :exc:`XapianError`\r
+ A Xapian exception occurred, mtime not stored.\r
+- STATUS.READ_ONLY_DATABASE\r
++ :exc:`ReadOnlyDatabaseError`\r
+ Database was opened in read-only mode so directory\r
+ mtime cannot be modified.\r
+- STATUS.NOT_INITIALIZED\r
++ :exc:`NotInitializedError`\r
+ The directory has not been initialized\r
+ """\r
+ self._assert_dir_is_initialized()\r
+@@ -712,7 +725,7 @@ class Directory(object):\r
+ if status == STATUS.SUCCESS:\r
+ return\r
+ #fail with Exception otherwise\r
+- raise NotmuchError(status=status)\r
++ raise NotmuchError.decode(status)\r
+ \r
+ def get_mtime(self):\r
+ """Gets the mtime value of this directory in the database\r
+@@ -721,9 +734,9 @@ class Directory(object):\r
+ \r
+ :param mtime: A (time_t) timestamp\r
+ :returns: Nothing on success, raising an exception on failure.\r
+- :exception: :exc:`NotmuchError`:\r
++ :exception: :exc:`NotInitializedError`\r
+ \r
+- STATUS.NOT_INITIALIZED\r
++ :exc:`NotInitializedError`\r
+ The directory has not been initialized\r
+ """\r
+ self._assert_dir_is_initialized()\r
+@@ -743,6 +756,11 @@ class Directory(object):\r
+ \r
+ The returned filenames will be the basename-entries only (not\r
+ complete paths.\r
++\r
++ :exception: :exc:`NotInitializedError`\r
++\r
++ :exc:`NotInitializedError`\r
++ The directory has not been initialized\r
+ """\r
+ self._assert_dir_is_initialized()\r
+ \r
+@@ -755,6 +773,11 @@ class Directory(object):\r
+ \r
+ The returned filenames will be the basename-entries only (not\r
+ complete paths.\r
++\r
++ :exception: :exc:`NotInitializedError`\r
++\r
++ :exc:`NotInitializedError`\r
++ The directory has not been initialized\r
+ """\r
+ self._assert_dir_is_initialized()\r
+ \r
+@@ -801,7 +824,7 @@ class Filenames(object):\r
+ \r
+ def next(self):\r
+ if self._files_p is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ \r
+ if not nmlib.notmuch_filenames_valid(self._files_p):\r
+ self._files_p = None\r
+@@ -820,11 +843,16 @@ class Filenames(object):\r
+ #THIS FAILS\r
+ files = Database().get_directory('').get_child_files()\r
+ if len(files) > 0: #this 'exhausts' msgs\r
+- # next line raises NotmuchError(status=STATUS.NOT_INITIALIZED)!!!\r
++ # next line raises NotInitializedError()!!!\r
+ for file in files: print file\r
++\r
++ :exception: :exc:`NotInitializedError`\r
++\r
++ :exc:`NotInitializedError`\r
++ If self._files_p is None\r
+ """\r
+ if self._files_p is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ \r
+ i = 0\r
+ while nmlib.notmuch_filenames_valid(self._files_p):\r
+diff --git a/bindings/python/notmuch/filename.py b/bindings/python/notmuch/filename.py\r
+index c5dfd94..ddfd494 100644\r
+--- a/bindings/python/notmuch/filename.py\r
++++ b/bindings/python/notmuch/filename.py\r
+@@ -17,7 +17,8 @@ along with notmuch. If not, see <http://www.gnu.org/licenses/>.\r
+ Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>'\r
+ """\r
+ from ctypes import c_char_p\r
+-from notmuch.globals import nmlib, STATUS, NotmuchError\r
++from notmuch.globals import nmlib, STATUS, NotmuchError, \\r
++ NullPointerError, NotInitializedError\r
+ \r
+ \r
+ class Filenames(object):\r
+@@ -68,7 +69,7 @@ class Filenames(object):\r
+ once all derived objects are dead.\r
+ """\r
+ if files_p is None:\r
+- raise NotmuchError(status=STATUS.NULL_POINTER)\r
++ raise NullPointerError()\r
+ \r
+ self._files = files_p\r
+ #save reference to parent object so we keep it alive\r
+@@ -80,7 +81,7 @@ class Filenames(object):\r
+ This is the main function that will usually be used by the\r
+ user."""\r
+ if self._files is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ \r
+ if not nmlib.notmuch_filenames_valid(self._files):\r
+ self._files = None\r
+@@ -96,7 +97,7 @@ class Filenames(object):\r
+ .. note:: As this iterates over the filenames, we will not be\r
+ able to iterate over them again (as in retrieve them)! If\r
+ the tags have been exhausted already, this will raise a\r
+- :exc:`NotmuchError` STATUS.NOT_INITIALIZED on subsequent\r
++ :exc:`NotInitializedError` on subsequent\r
+ attempts. However, you can use\r
+ :meth:`Message.get_filenames` repeatedly to perform\r
+ various actions on filenames.\r
+diff --git a/bindings/python/notmuch/message.py b/bindings/python/notmuch/message.py\r
+index 5cc3175..ac708ec 100644\r
+--- a/bindings/python/notmuch/message.py\r
++++ b/bindings/python/notmuch/message.py\r
+@@ -21,7 +21,8 @@ Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>'\r
+ \r
+ from ctypes import c_char_p, c_void_p, c_long, c_uint, c_int\r
+ from datetime import date\r
+-from notmuch.globals import nmlib, STATUS, NotmuchError, Enum, _str\r
++from notmuch.globals import nmlib, STATUS, Enum, _str, NotmuchError, \\r
++ NullPointerError, NotInitializedError\r
+ from notmuch.tag import Tags\r
+ from notmuch.filename import Filenames\r
+ import sys\r
+@@ -42,7 +43,7 @@ class Messages(object):\r
+ only provides a one-time iterator (it cannot reset the iterator to\r
+ the start). Thus iterating over the function will "exhaust" the list\r
+ of messages, and a subsequent iteration attempt will raise a\r
+- :exc:`NotmuchError` STATUS.NOT_INITIALIZED. If you need to\r
++ :exc:`NotInitializedError`. If you need to\r
+ re-iterate over a list of messages you will need to retrieve a new\r
+ :class:`Messages` object or cache your :class:`Message`\s in a list\r
+ via::\r
+@@ -115,7 +116,7 @@ class Messages(object):\r
+ the Python object.(?)\r
+ """\r
+ if msgs_p is None:\r
+- raise NotmuchError(status=STATUS.NULL_POINTER)\r
++ raise NullPointerError()\r
+ \r
+ self._msgs = msgs_p\r
+ #store parent, so we keep them alive as long as self is alive\r
+@@ -125,13 +126,13 @@ class Messages(object):\r
+ """Return the unique :class:`Tags` in the contained messages\r
+ \r
+ :returns: :class:`Tags`\r
+- :exceptions: :exc:`NotmuchError` STATUS.NOT_INITIALIZED if not inited\r
++ :exceptions: :exc:`NotInitializedError` if not inited\r
+ \r
+ .. note:: :meth:`collect_tags` will iterate over the messages and\r
+ therefore will not allow further iterations.\r
+ """\r
+ if self._msgs is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ \r
+ # collect all tags (returns NULL on error)\r
+ tags_p = Messages._collect_tags(self._msgs)\r
+@@ -139,7 +140,7 @@ class Messages(object):\r
+ self._msgs = None\r
+ \r
+ if tags_p == None:\r
+- raise NotmuchError(status=STATUS.NULL_POINTER)\r
++ raise NullPointerError()\r
+ return Tags(tags_p, self)\r
+ \r
+ def __iter__(self):\r
+@@ -148,7 +149,7 @@ class Messages(object):\r
+ \r
+ def next(self):\r
+ if self._msgs is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ \r
+ if not nmlib.notmuch_messages_valid(self._msgs):\r
+ self._msgs = None\r
+@@ -292,7 +293,7 @@ class Message(object):\r
+ objects are dead.\r
+ """\r
+ if msg_p is None:\r
+- raise NotmuchError(status=STATUS.NULL_POINTER)\r
++ raise NullPointerError()\r
+ self._msg = msg_p\r
+ #keep reference to parent, so we keep it alive\r
+ self._parent = parent\r
+@@ -301,11 +302,11 @@ class Message(object):\r
+ """Returns the message ID\r
+ \r
+ :returns: String with a message ID\r
+- :exception: :exc:`NotmuchError` STATUS.NOT_INITIALIZED if the message\r
++ :exception: :exc:`NotInitializedError` if the message\r
+ is not initialized.\r
+ """\r
+ if self._msg is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ return Message._get_message_id(self._msg)\r
+ \r
+ def get_thread_id(self):\r
+@@ -318,11 +319,11 @@ class Message(object):\r
+ message belongs to a single thread.\r
+ \r
+ :returns: String with a thread ID\r
+- :exception: :exc:`NotmuchError` STATUS.NOT_INITIALIZED if the message\r
++ :exception: :exc:`NotInitializedError` if the message\r
+ is not initialized.\r
+ """\r
+ if self._msg is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ \r
+ return Message._get_thread_id(self._msg)\r
+ \r
+@@ -341,11 +342,11 @@ class Message(object):\r
+ \r
+ :returns: :class:`Messages` or `None` if there are no replies to\r
+ this message.\r
+- :exception: :exc:`NotmuchError` STATUS.NOT_INITIALIZED if the message\r
++ :exception: :exc:`NotInitializedError` if the message\r
+ is not initialized.\r
+ """\r
+ if self._msg is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ \r
+ msgs_p = Message._get_replies(self._msg)\r
+ \r
+@@ -363,11 +364,11 @@ class Message(object):\r
+ \r
+ :returns: A time_t timestamp.\r
+ :rtype: c_unit64\r
+- :exception: :exc:`NotmuchError` STATUS.NOT_INITIALIZED if the message\r
++ :exception: :exc:`NotInitializedError` if the message\r
+ is not initialized.\r
+ """\r
+ if self._msg is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ return Message._get_date(self._msg)\r
+ \r
+ def get_header(self, header):\r
+@@ -389,23 +390,23 @@ class Message(object):\r
+ * STATUS.NULL_POINTER, if no header was found\r
+ """\r
+ if self._msg is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ \r
+ #Returns NULL if any error occurs.\r
+ header = Message._get_header(self._msg, header)\r
+ if header == None:\r
+- raise NotmuchError(status=STATUS.NULL_POINTER)\r
++ raise NullPointerError()\r
+ return header.decode('UTF-8')\r
+ \r
+ def get_filename(self):\r
+ """Returns the file path of the message file\r
+ \r
+ :returns: Absolute file path & name of the message file\r
+- :exception: :exc:`NotmuchError` STATUS.NOT_INITIALIZED if the message\r
++ :exception: :exc:`NotInitializedError` if the message\r
+ is not initialized.\r
+ """\r
+ if self._msg is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ return Message._get_filename(self._msg)\r
+ \r
+ def get_filenames(self):\r
+@@ -415,7 +416,7 @@ class Message(object):\r
+ messages recorded to have the same Message-ID. These files must\r
+ not necessarily have identical content."""\r
+ if self._msg is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ \r
+ files_p = Message._get_filenames(self._msg)\r
+ \r
+@@ -431,11 +432,11 @@ class Message(object):\r
+ :param flag: One of the :attr:`Message.FLAG` values (currently only\r
+ *Message.FLAG.MATCH*\r
+ :returns: An unsigned int (0/1), indicating whether the flag is set.\r
+- :exception: :exc:`NotmuchError` STATUS.NOT_INITIALIZED if the message\r
++ :exception: :exc:`NotInitializedError` if the message\r
+ is not initialized.\r
+ """\r
+ if self._msg is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ return Message._get_flag(self._msg, flag)\r
+ \r
+ def set_flag(self, flag, value):\r
+@@ -446,11 +447,11 @@ class Message(object):\r
+ :param value: A bool indicating whether to set or unset the flag.\r
+ \r
+ :returns: Nothing\r
+- :exception: :exc:`NotmuchError` STATUS.NOT_INITIALIZED if the message\r
++ :exception: :exc:`NotInitializedError` if the message\r
+ is not initialized.\r
+ """\r
+ if self._msg is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ nmlib.notmuch_message_set_flag(self._msg, flag, value)\r
+ \r
+ def get_tags(self):\r
+@@ -464,11 +465,11 @@ class Message(object):\r
+ * STATUS.NULL_POINTER, on error\r
+ """\r
+ if self._msg is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ \r
+ tags_p = Message._get_tags(self._msg)\r
+ if tags_p == None:\r
+- raise NotmuchError(status=STATUS.NULL_POINTER)\r
++ raise NullPointerError()\r
+ return Tags(tags_p, self)\r
+ \r
+ def add_tag(self, tag, sync_maildir_flags=False):\r
+@@ -503,13 +504,13 @@ class Message(object):\r
+ The message has not been initialized.\r
+ """\r
+ if self._msg is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ \r
+ status = nmlib.notmuch_message_add_tag(self._msg, _str(tag))\r
+ \r
+ # bail out on failure\r
+ if status != STATUS.SUCCESS:\r
+- raise NotmuchError(status=status)\r
++ raise NotmuchError.decode(status)\r
+ \r
+ if sync_maildir_flags:\r
+ self.tags_to_maildir_flags()\r
+@@ -547,12 +548,12 @@ class Message(object):\r
+ The message has not been initialized.\r
+ """\r
+ if self._msg is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ \r
+ status = nmlib.notmuch_message_remove_tag(self._msg, _str(tag))\r
+ # bail out on error\r
+ if status != STATUS.SUCCESS:\r
+- raise NotmuchError(status=status)\r
++ raise NotmuchError.decode(status)\r
+ \r
+ if sync_maildir_flags:\r
+ self.tags_to_maildir_flags()\r
+@@ -584,13 +585,13 @@ class Message(object):\r
+ The message has not been initialized.\r
+ """\r
+ if self._msg is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ \r
+ status = nmlib.notmuch_message_remove_all_tags(self._msg)\r
+ \r
+ # bail out on error\r
+ if status != STATUS.SUCCESS:\r
+- raise NotmuchError(status=status)\r
++ raise NotmuchError.decode(status)\r
+ \r
+ if sync_maildir_flags:\r
+ self.tags_to_maildir_flags()\r
+@@ -638,7 +639,7 @@ class Message(object):\r
+ The message has not been initialized.\r
+ """\r
+ if self._msg is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ \r
+ status = nmlib.notmuch_message_freeze(self._msg)\r
+ \r
+@@ -646,7 +647,7 @@ class Message(object):\r
+ # return on success\r
+ return status\r
+ \r
+- raise NotmuchError(status=status)\r
++ raise NotmuchError.decode(status)\r
+ \r
+ def thaw(self):\r
+ """Thaws the current 'message'\r
+@@ -673,7 +674,7 @@ class Message(object):\r
+ The message has not been initialized.\r
+ """\r
+ if self._msg is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ \r
+ status = nmlib.notmuch_message_thaw(self._msg)\r
+ \r
+@@ -681,7 +682,7 @@ class Message(object):\r
+ # return on success\r
+ return status\r
+ \r
+- raise NotmuchError(status=status)\r
++ raise NotmuchError.decode(status)\r
+ \r
+ def is_match(self):\r
+ """(Not implemented)"""\r
+@@ -709,7 +710,7 @@ class Message(object):\r
+ :returns: a :class:`STATUS`. In short, you want to see\r
+ notmuch.STATUS.SUCCESS here. See there for details."""\r
+ if self._msg is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ status = Message._tags_to_maildir_flags(self._msg)\r
+ \r
+ def maildir_flags_to_tags(self):\r
+@@ -736,7 +737,7 @@ class Message(object):\r
+ :returns: a :class:`STATUS`. In short, you want to see\r
+ notmuch.STATUS.SUCCESS here. See there for details."""\r
+ if self._msg is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ status = Message._tags_to_maildir_flags(self._msg)\r
+ \r
+ def __repr__(self):\r
+diff --git a/bindings/python/notmuch/tag.py b/bindings/python/notmuch/tag.py\r
+index 9ca871a..b903864 100644\r
+--- a/bindings/python/notmuch/tag.py\r
++++ b/bindings/python/notmuch/tag.py\r
+@@ -17,7 +17,9 @@ along with notmuch. If not, see <http://www.gnu.org/licenses/>.\r
+ Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>'\r
+ """\r
+ from ctypes import c_char_p\r
+-from notmuch.globals import nmlib, STATUS, NotmuchError\r
++from notmuch.globals import nmlib, STATUS, NotmuchError, \\r
++ NullPointerError, NotInitializedError\r
++\r
+ \r
+ \r
+ class Tags(object):\r
+@@ -70,7 +72,7 @@ class Tags(object):\r
+ cache the tags in the Python object(?)\r
+ """\r
+ if tags_p is None:\r
+- raise NotmuchError(status=STATUS.NULL_POINTER)\r
++ raise NullPointerError()\r
+ \r
+ self._tags = tags_p\r
+ #save reference to parent object so we keep it alive\r
+@@ -82,7 +84,7 @@ class Tags(object):\r
+ \r
+ def next(self):\r
+ if self._tags is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ if not nmlib.notmuch_tags_valid(self._tags):\r
+ self._tags = None\r
+ raise StopIteration\r
+@@ -107,7 +109,7 @@ class Tags(object):\r
+ .. note:: As this iterates over the tags, we will not be able\r
+ to iterate over them again (as in retrieve them)! If\r
+ the tags have been exhausted already, this will raise a\r
+- :exc:`NotmuchError` STATUS.NOT_INITIALIZED on\r
++ :exc:`NotInitializedError` on\r
+ subsequent attempts.\r
+ """\r
+ return " ".join(self)\r
+diff --git a/bindings/python/notmuch/thread.py b/bindings/python/notmuch/thread.py\r
+index 93089d0..e9d1185 100644\r
+--- a/bindings/python/notmuch/thread.py\r
++++ b/bindings/python/notmuch/thread.py\r
+@@ -18,7 +18,8 @@ Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>'\r
+ """\r
+ \r
+ from ctypes import c_char_p, c_void_p, c_long\r
+-from notmuch.globals import nmlib, STATUS, NotmuchError\r
++from notmuch.globals import nmlib, STATUS, NotmuchError, \\r
++ NullPointerError, NotInitializedError\r
+ from notmuch.message import Messages\r
+ from notmuch.tag import Tags\r
+ from datetime import date\r
+@@ -33,7 +34,7 @@ class Threads(object):\r
+ library only provides a one-time iterator (it cannot reset the\r
+ iterator to the start). Thus iterating over the function will\r
+ "exhaust" the list of threads, and a subsequent iteration attempt\r
+- will raise a :exc:`NotmuchError` STATUS.NOT_INITIALIZED. Also\r
++ will raise a :exc:`NotInitializedError`. Also\r
+ note, that any function that uses iteration will also\r
+ exhaust the messages. So both::\r
+ \r
+@@ -95,7 +96,7 @@ class Threads(object):\r
+ the Python object.(?)\r
+ """\r
+ if threads_p is None:\r
+- raise NotmuchError(status=STATUS.NULL_POINTER)\r
++ raise NullPointerError()\r
+ \r
+ self._threads = threads_p\r
+ #store parent, so we keep them alive as long as self is alive\r
+@@ -107,7 +108,7 @@ class Threads(object):\r
+ \r
+ def next(self):\r
+ if self._threads is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ \r
+ if not nmlib.notmuch_threads_valid(self._threads):\r
+ self._threads = None\r
+@@ -126,11 +127,11 @@ class Threads(object):\r
+ #THIS FAILS\r
+ threads = Database().create_query('').search_threads()\r
+ if len(threads) > 0: #this 'exhausts' threads\r
+- # next line raises NotmuchError(status=STATUS.NOT_INITIALIZED)!!!\r
++ # next line raises NotInitializedError()!!!\r
+ for thread in threads: print thread\r
+ """\r
+ if self._threads is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ \r
+ i = 0\r
+ # returns 'bool'. On out-of-memory it returns None\r
+@@ -206,7 +207,7 @@ class Thread(object):\r
+ objects are dead.\r
+ """\r
+ if thread_p is None:\r
+- raise NotmuchError(status=STATUS.NULL_POINTER)\r
++ raise NullPointerError()\r
+ self._thread = thread_p\r
+ #keep reference to parent, so we keep it alive\r
+ self._parent = parent\r
+@@ -218,11 +219,11 @@ class Thread(object):\r
+ for as long as the thread is valid.\r
+ \r
+ :returns: String with a message ID\r
+- :exception: :exc:`NotmuchError` STATUS.NOT_INITIALIZED if the thread\r
++ :exception: :exc:`NotInitializedError` if the thread\r
+ is not initialized.\r
+ """\r
+ if self._thread is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ return Thread._get_thread_id(self._thread)\r
+ \r
+ def get_total_messages(self):\r
+@@ -231,11 +232,11 @@ class Thread(object):\r
+ :returns: The number of all messages in the database\r
+ belonging to this thread. Contrast with\r
+ :meth:`get_matched_messages`.\r
+- :exception: :exc:`NotmuchError` STATUS.NOT_INITIALIZED if the thread\r
++ :exception: :exc:`NotInitializedError` if the thread\r
+ is not initialized.\r
+ """\r
+ if self._thread is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ return nmlib.notmuch_thread_get_total_messages(self._thread)\r
+ \r
+ def get_toplevel_messages(self):\r
+@@ -258,12 +259,12 @@ class Thread(object):\r
+ * STATUS.NULL_POINTER if search_messages failed\r
+ """\r
+ if self._thread is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ \r
+ msgs_p = Thread._get_toplevel_messages(self._thread)\r
+ \r
+ if msgs_p is None:\r
+- raise NotmuchError(status=STATUS.NULL_POINTER)\r
++ raise NullPointerError()\r
+ \r
+ return Messages(msgs_p, self)\r
+ \r
+@@ -273,11 +274,11 @@ class Thread(object):\r
+ :returns: The number of all messages belonging to this thread that\r
+ matched the :class:`Query`from which this thread was created.\r
+ Contrast with :meth:`get_total_messages`.\r
+- :exception: :exc:`NotmuchError` STATUS.NOT_INITIALIZED if the thread\r
++ :exception: :exc:`NotInitializedError` if the thread\r
+ is not initialized.\r
+ """\r
+ if self._thread is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ return nmlib.notmuch_thread_get_matched_messages(self._thread)\r
+ \r
+ def get_authors(self):\r
+@@ -291,7 +292,7 @@ class Thread(object):\r
+ as long as this Thread() is not deleted.\r
+ """\r
+ if self._thread is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ authors = Thread._get_authors(self._thread)\r
+ if authors is None:\r
+ return None\r
+@@ -304,7 +305,7 @@ class Thread(object):\r
+ as long as this Thread() is not deleted.\r
+ """\r
+ if self._thread is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ subject = Thread._get_subject(self._thread)\r
+ if subject is None:\r
+ return None\r
+@@ -315,11 +316,11 @@ class Thread(object):\r
+ \r
+ :returns: A time_t timestamp.\r
+ :rtype: c_unit64\r
+- :exception: :exc:`NotmuchError` STATUS.NOT_INITIALIZED if the message\r
++ :exception: :exc:`NotInitializedError` if the message\r
+ is not initialized.\r
+ """\r
+ if self._thread is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ return Thread._get_newest_date(self._thread)\r
+ \r
+ def get_oldest_date(self):\r
+@@ -327,11 +328,11 @@ class Thread(object):\r
+ \r
+ :returns: A time_t timestamp.\r
+ :rtype: c_unit64\r
+- :exception: :exc:`NotmuchError` STATUS.NOT_INITIALIZED if the message\r
++ :exception: :exc:`NotInitializedError` if the message\r
+ is not initialized.\r
+ """\r
+ if self._thread is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ return Thread._get_oldest_date(self._thread)\r
+ \r
+ def get_tags(self):\r
+@@ -354,11 +355,11 @@ class Thread(object):\r
+ * STATUS.NULL_POINTER, on error\r
+ """\r
+ if self._thread is None:\r
+- raise NotmuchError(status=STATUS.NOT_INITIALIZED)\r
++ raise NotInitializedError()\r
+ \r
+ tags_p = Thread._get_tags(self._thread)\r
+ if tags_p == None:\r
+- raise NotmuchError(status=STATUS.NULL_POINTER)\r
++ raise NullPointerError()\r
+ return Tags(tags_p, self)\r
+ \r
+ def __str__(self):\r
+-- \r
+1.7.6.3\r
+\r