From 76a2db3d7b92bc1a8be75f673dc384c46cf02fab Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Wed, 22 Feb 2012 22:39:52 +0100 Subject: python: move Threads class into its own file Signed-off-by: Justus Winter <4winter@informatik.uni-hamburg.de> --- bindings/python/notmuch/threads.py | 178 +++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 bindings/python/notmuch/threads.py (limited to 'bindings/python/notmuch/threads.py') diff --git a/bindings/python/notmuch/threads.py b/bindings/python/notmuch/threads.py new file mode 100644 index 0000000..9d305e2 --- /dev/null +++ b/bindings/python/notmuch/threads.py @@ -0,0 +1,178 @@ +""" +This file is part of notmuch. + +Notmuch is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation, either version 3 of the License, or (at your +option) any later version. + +Notmuch is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with notmuch. If not, see . + +Copyright 2010 Sebastian Spaeth ' +""" + +from notmuch.globals import ( + nmlib, + Python3StringMixIn, + NullPointerError, + NotInitializedError, + NotmuchThreadP, + NotmuchThreadsP, +) +from .thread import Thread + +class Threads(Python3StringMixIn): + """Represents a list of notmuch threads + + This object provides an iterator over a list of notmuch threads + (Technically, it provides a wrapper for the underlying + *notmuch_threads_t* structure). 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 threads, and a subsequent iteration attempt + will raise a :exc:`NotInitializedError`. Also + note, that any function that uses iteration will also + exhaust the messages. So both:: + + for thread in threads: print thread + + as well as:: + + number_of_msgs = len(threads) + + will "exhaust" the threads. If you need to re-iterate over a list of + messages you will need to retrieve a new :class:`Threads` object. + + Things are not as bad as it seems though, you can store and reuse + the single Thread objects as often as you want as long as you + keep the parent Threads object around. (Recall that due to + hierarchical memory allocation, all derived Threads objects will + be invalid when we delete the parent Threads() object, even if it + was already "exhausted".) So this works:: + + db = Database() + threads = Query(db,'').search_threads() #get a Threads() object + threadlist = [] + for thread in threads: + threadlist.append(thread) + + # threads is "exhausted" now and even len(threads) will raise an + # exception. + # However it will be kept around until all retrieved Thread() objects are + # also deleted. If you did e.g. an explicit del(threads) here, the + # following lines would fail. + + # You can reiterate over *threadlist* however as often as you want. + # It is simply a list with Thread objects. + + print (threadlist[0].get_thread_id()) + print (threadlist[1].get_thread_id()) + print (threadlist[0].get_total_messages()) + """ + + #notmuch_threads_get + _get = nmlib.notmuch_threads_get + _get.argtypes = [NotmuchThreadsP] + _get.restype = NotmuchThreadP + + def __init__(self, threads_p, parent=None): + """ + :param threads_p: A pointer to an underlying *notmuch_threads_t* + structure. These are not publically exposed, so a user + 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:`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 + a reference to it, so we can automatically delete the db + object once all derived objects are dead. + :TODO: Make the iterator work more than once and cache the tags in + the Python object.(?) + """ + if not threads_p: + raise NullPointerError() + + self._threads = threads_p + #store parent, so we keep them alive as long as self is alive + self._parent = parent + + def __iter__(self): + """ Make Threads an iterator """ + return self + + _valid = nmlib.notmuch_threads_valid + _valid.argtypes = [NotmuchThreadsP] + _valid.restype = bool + + _move_to_next = nmlib.notmuch_threads_move_to_next + _move_to_next.argtypes = [NotmuchThreadsP] + _move_to_next.restype = None + + def __next__(self): + if not self._threads: + raise NotInitializedError() + + if not self._valid(self._threads): + self._threads = None + raise StopIteration + + thread = Thread(Threads._get(self._threads), self) + self._move_to_next(self._threads) + return thread + next = __next__ # python2.x iterator protocol compatibility + + def __len__(self): + """len(:class:`Threads`) returns the number of contained Threads + + .. note:: As this iterates over the threads, we will not be able to + iterate over them again! So this will fail:: + + #THIS FAILS + threads = Database().create_query('').search_threads() + if len(threads) > 0: #this 'exhausts' threads + # next line raises :exc:`NotInitializedError`!!! + for thread in threads: print thread + """ + if not self._threads: + raise NotInitializedError() + + i = 0 + # returns 'bool'. On out-of-memory it returns None + while self._valid(self._threads): + self._move_to_next(self._threads) + i += 1 + # reset self._threads to mark as "exhausted" + self._threads = None + return i + + def __nonzero__(self): + """Check if :class:`Threads` contains at least one more valid thread + + The existence of this function makes 'if Threads: foo' work, as + that will implicitely call len() exhausting the iterator if + __nonzero__ does not exist. This function makes `bool(Threads())` + work repeatedly. + + :return: True if there is at least one more thread in the + Iterator, False if not. None on a "Out-of-memory" error. + """ + return self._threads is not None and \ + self._valid(self._threads) > 0 + + _destroy = nmlib.notmuch_threads_destroy + _destroy.argtypes = [NotmuchThreadsP] + _destroy.argtypes = None + + def __del__(self): + """Close and free the notmuch Threads""" + if self._threads is not None: + self._destroy(self._threads) -- cgit v1.2.3 From a7561cc20b17669784c3259afcbcef98029f93e9 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Thu, 23 Feb 2012 00:11:22 +0100 Subject: python: move the exception classes into error.py Signed-off-by: Justus Winter <4winter@informatik.uni-hamburg.de> --- bindings/python/notmuch/__init__.py | 4 +- bindings/python/notmuch/database.py | 14 +-- bindings/python/notmuch/directory.py | 6 +- bindings/python/notmuch/errors.py | 183 +++++++++++++++++++++++++++++++++++ bindings/python/notmuch/filenames.py | 6 +- bindings/python/notmuch/globals.py | 160 +----------------------------- bindings/python/notmuch/message.py | 10 +- bindings/python/notmuch/messages.py | 6 +- bindings/python/notmuch/query.py | 2 + bindings/python/notmuch/tag.py | 4 +- bindings/python/notmuch/thread.py | 6 +- bindings/python/notmuch/threads.py | 6 +- 12 files changed, 225 insertions(+), 182 deletions(-) create mode 100644 bindings/python/notmuch/errors.py (limited to 'bindings/python/notmuch/threads.py') diff --git a/bindings/python/notmuch/__init__.py b/bindings/python/notmuch/__init__.py index fddc492..5561624 100644 --- a/bindings/python/notmuch/__init__.py +++ b/bindings/python/notmuch/__init__.py @@ -60,8 +60,8 @@ from .query import Query from .tag import Tags from .thread import Thread from .threads import Threads -from .globals import ( - nmlib, +from .globals import nmlib +from .errors import ( STATUS, NotmuchError, OutOfMemoryError, diff --git a/bindings/python/notmuch/database.py b/bindings/python/notmuch/database.py index 800264b..44d40fd 100644 --- a/bindings/python/notmuch/database.py +++ b/bindings/python/notmuch/database.py @@ -22,12 +22,6 @@ import codecs from ctypes import c_char_p, c_void_p, c_uint, byref, POINTER from notmuch.globals import ( nmlib, - STATUS, - FileError, - NotmuchError, - NullPointerError, - NotInitializedError, - ReadOnlyDatabaseError, Enum, _str, NotmuchDatabaseP, @@ -35,6 +29,14 @@ from notmuch.globals import ( NotmuchMessageP, NotmuchTagsP, ) +from .errors import ( + STATUS, + FileError, + NotmuchError, + NullPointerError, + NotInitializedError, + ReadOnlyDatabaseError, +) from notmuch.message import Message from notmuch.tag import Tags from .query import Query diff --git a/bindings/python/notmuch/directory.py b/bindings/python/notmuch/directory.py index b679aa2..0c5e015 100644 --- a/bindings/python/notmuch/directory.py +++ b/bindings/python/notmuch/directory.py @@ -20,11 +20,13 @@ Copyright 2010 Sebastian Spaeth ' from ctypes import c_uint, c_long from notmuch.globals import ( nmlib, + NotmuchDirectoryP, + NotmuchFilenamesP +) +from .errors import ( STATUS, NotmuchError, NotInitializedError, - NotmuchDirectoryP, - NotmuchFilenamesP ) from .filenames import Filenames diff --git a/bindings/python/notmuch/errors.py b/bindings/python/notmuch/errors.py new file mode 100644 index 0000000..f153a9c --- /dev/null +++ b/bindings/python/notmuch/errors.py @@ -0,0 +1,183 @@ +""" +This file is part of notmuch. + +Notmuch is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation, either version 3 of the License, or (at your +option) any later version. + +Notmuch is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with notmuch. If not, see . + +Copyright 2010 Sebastian Spaeth +""" + +from ctypes import c_char_p, c_int + +from .globals import ( + nmlib, + Enum, + Python3StringMixIn, +) + +class Status(Enum): + """Enum with a string representation of a notmuch_status_t value.""" + _status2str = nmlib.notmuch_status_to_string + _status2str.restype = c_char_p + _status2str.argtypes = [c_int] + + def __init__(self, statuslist): + """It is initialized with a list of strings that are available as + Status().string1 - Status().stringn attributes. + """ + super(Status, self).__init__(statuslist) + + @classmethod + def status2str(self, status): + """Get a (unicode) string representation of a notmuch_status_t value.""" + # define strings for custom error messages + if status == STATUS.NOT_INITIALIZED: + return "Operation on uninitialized object impossible." + return unicode(Status._status2str(status)) + +STATUS = Status(['SUCCESS', + 'OUT_OF_MEMORY', + 'READ_ONLY_DATABASE', + 'XAPIAN_EXCEPTION', + 'FILE_ERROR', + 'FILE_NOT_EMAIL', + 'DUPLICATE_MESSAGE_ID', + 'NULL_POINTER', + 'TAG_TOO_LONG', + 'UNBALANCED_FREEZE_THAW', + 'UNBALANCED_ATOMIC', + 'NOT_INITIALIZED']) +"""STATUS is a class, whose attributes provide constants that serve as return +indicators for notmuch functions. Currently the following ones are defined. For +possible return values and specific meaning for each method, see the method +description. + + * SUCCESS + * OUT_OF_MEMORY + * READ_ONLY_DATABASE + * XAPIAN_EXCEPTION + * FILE_ERROR + * FILE_NOT_EMAIL + * DUPLICATE_MESSAGE_ID + * NULL_POINTER + * TAG_TOO_LONG + * UNBALANCED_FREEZE_THAW + * UNBALANCED_ATOMIC + * NOT_INITIALIZED + +Invoke the class method `notmuch.STATUS.status2str` with a status value as +argument to receive a human readable string""" +STATUS.__name__ = 'STATUS' + + +class NotmuchError(Exception, Python3StringMixIn): + """Is initiated with a (notmuch.STATUS[, message=None]). It will not + return an instance of the class NotmuchError, but a derived instance + of a more specific Error Message, e.g. OutOfMemoryError. Each status + but SUCCESS has a corresponding subclassed Exception.""" + + @classmethod + def get_exc_subclass(cls, status): + """Returns a fine grained Exception() type, + detailing the error status""" + subclasses = { + STATUS.OUT_OF_MEMORY: OutOfMemoryError, + STATUS.READ_ONLY_DATABASE: ReadOnlyDatabaseError, + STATUS.XAPIAN_EXCEPTION: XapianError, + STATUS.FILE_ERROR: FileError, + STATUS.FILE_NOT_EMAIL: FileNotEmailError, + STATUS.DUPLICATE_MESSAGE_ID: DuplicateMessageIdError, + STATUS.NULL_POINTER: NullPointerError, + STATUS.TAG_TOO_LONG: TagTooLongError, + STATUS.UNBALANCED_FREEZE_THAW: UnbalancedFreezeThawError, + STATUS.UNBALANCED_ATOMIC: UnbalancedAtomicError, + STATUS.NOT_INITIALIZED: NotInitializedError, + } + assert 0 < status <= len(subclasses) + return subclasses[status] + + def __new__(cls, *args, **kwargs): + """Return a correct subclass of NotmuchError if needed + + We return a NotmuchError instance if status is None (or 0) and a + subclass that inherits from NotmuchError depending on the + 'status' parameter otherwise.""" + # get 'status'. Passed in as arg or kwarg? + status = args[0] if len(args) else kwargs.get('status', None) + # no 'status' or cls is subclass already, return 'cls' instance + if not status or cls != NotmuchError: + return super(NotmuchError, cls).__new__(cls) + subclass = cls.get_exc_subclass(status) # which class to use? + return subclass.__new__(subclass, *args, **kwargs) + + def __init__(self, status=None, message=None): + self.status = status + self.message = message + + def __unicode__(self): + if self.message is not None: + return self.message + elif self.status is not None: + return STATUS.status2str(self.status) + else: + return 'Unknown error' + + +# List of Subclassed exceptions that correspond to STATUS values and are +# subclasses of NotmuchError. +class OutOfMemoryError(NotmuchError): + status = STATUS.OUT_OF_MEMORY + + +class ReadOnlyDatabaseError(NotmuchError): + status = STATUS.READ_ONLY_DATABASE + + +class XapianError(NotmuchError): + status = STATUS.XAPIAN_EXCEPTION + + +class FileError(NotmuchError): + status = STATUS.FILE_ERROR + + +class FileNotEmailError(NotmuchError): + status = STATUS.FILE_NOT_EMAIL + + +class DuplicateMessageIdError(NotmuchError): + status = STATUS.DUPLICATE_MESSAGE_ID + + +class NullPointerError(NotmuchError): + status = STATUS.NULL_POINTER + + +class TagTooLongError(NotmuchError): + status = STATUS.TAG_TOO_LONG + + +class UnbalancedFreezeThawError(NotmuchError): + status = STATUS.UNBALANCED_FREEZE_THAW + + +class UnbalancedAtomicError(NotmuchError): + status = STATUS.UNBALANCED_ATOMIC + + +class NotInitializedError(NotmuchError): + """Derived from NotmuchError, this occurs if the underlying data + structure (e.g. database is not initialized (yet) or an iterator has + been exhausted. You can test for NotmuchError with .status = + STATUS.NOT_INITIALIZED""" + status = STATUS.NOT_INITIALIZED diff --git a/bindings/python/notmuch/filenames.py b/bindings/python/notmuch/filenames.py index 232a9ed..12050df 100644 --- a/bindings/python/notmuch/filenames.py +++ b/bindings/python/notmuch/filenames.py @@ -19,12 +19,14 @@ Copyright 2010 Sebastian Spaeth ' from ctypes import c_char_p from notmuch.globals import ( nmlib, - NullPointerError, - NotInitializedError, NotmuchMessageP, NotmuchFilenamesP, Python3StringMixIn, ) +from .errors import ( + NullPointerError, + NotInitializedError, +) class Filenames(Python3StringMixIn): diff --git a/bindings/python/notmuch/globals.py b/bindings/python/notmuch/globals.py index 4138460..442f3e3 100644 --- a/bindings/python/notmuch/globals.py +++ b/bindings/python/notmuch/globals.py @@ -17,7 +17,7 @@ along with notmuch. If not, see . Copyright 2010 Sebastian Spaeth ' """ import sys -from ctypes import CDLL, c_char_p, c_int, Structure, POINTER +from ctypes import CDLL, Structure, POINTER #----------------------------------------------------------------------------- #package-global instance of the notmuch library @@ -66,164 +66,6 @@ class Enum(object): setattr(self, name, number) -class Status(Enum): - """Enum with a string representation of a notmuch_status_t value.""" - _status2str = nmlib.notmuch_status_to_string - _status2str.restype = c_char_p - _status2str.argtypes = [c_int] - - def __init__(self, statuslist): - """It is initialized with a list of strings that are available as - Status().string1 - Status().stringn attributes. - """ - super(Status, self).__init__(statuslist) - - @classmethod - def status2str(self, status): - """Get a (unicode) string representation of a notmuch_status_t value.""" - # define strings for custom error messages - if status == STATUS.NOT_INITIALIZED: - return "Operation on uninitialized object impossible." - return unicode(Status._status2str(status)) - -STATUS = Status(['SUCCESS', - 'OUT_OF_MEMORY', - 'READ_ONLY_DATABASE', - 'XAPIAN_EXCEPTION', - 'FILE_ERROR', - 'FILE_NOT_EMAIL', - 'DUPLICATE_MESSAGE_ID', - 'NULL_POINTER', - 'TAG_TOO_LONG', - 'UNBALANCED_FREEZE_THAW', - 'UNBALANCED_ATOMIC', - 'NOT_INITIALIZED']) -"""STATUS is a class, whose attributes provide constants that serve as return -indicators for notmuch functions. Currently the following ones are defined. For -possible return values and specific meaning for each method, see the method -description. - - * SUCCESS - * OUT_OF_MEMORY - * READ_ONLY_DATABASE - * XAPIAN_EXCEPTION - * FILE_ERROR - * FILE_NOT_EMAIL - * DUPLICATE_MESSAGE_ID - * NULL_POINTER - * TAG_TOO_LONG - * UNBALANCED_FREEZE_THAW - * UNBALANCED_ATOMIC - * NOT_INITIALIZED - -Invoke the class method `notmuch.STATUS.status2str` with a status value as -argument to receive a human readable string""" -STATUS.__name__ = 'STATUS' - - -class NotmuchError(Exception, Python3StringMixIn): - """Is initiated with a (notmuch.STATUS[, message=None]). It will not - return an instance of the class NotmuchError, but a derived instance - of a more specific Error Message, e.g. OutOfMemoryError. Each status - but SUCCESS has a corresponding subclassed Exception.""" - - @classmethod - def get_exc_subclass(cls, status): - """Returns a fine grained Exception() type, - detailing the error status""" - subclasses = { - STATUS.OUT_OF_MEMORY: OutOfMemoryError, - STATUS.READ_ONLY_DATABASE: ReadOnlyDatabaseError, - STATUS.XAPIAN_EXCEPTION: XapianError, - STATUS.FILE_ERROR: FileError, - STATUS.FILE_NOT_EMAIL: FileNotEmailError, - STATUS.DUPLICATE_MESSAGE_ID: DuplicateMessageIdError, - STATUS.NULL_POINTER: NullPointerError, - STATUS.TAG_TOO_LONG: TagTooLongError, - STATUS.UNBALANCED_FREEZE_THAW: UnbalancedFreezeThawError, - STATUS.UNBALANCED_ATOMIC: UnbalancedAtomicError, - STATUS.NOT_INITIALIZED: NotInitializedError, - } - assert 0 < status <= len(subclasses) - return subclasses[status] - - def __new__(cls, *args, **kwargs): - """Return a correct subclass of NotmuchError if needed - - We return a NotmuchError instance if status is None (or 0) and a - subclass that inherits from NotmuchError depending on the - 'status' parameter otherwise.""" - # get 'status'. Passed in as arg or kwarg? - status = args[0] if len(args) else kwargs.get('status', None) - # no 'status' or cls is subclass already, return 'cls' instance - if not status or cls != NotmuchError: - return super(NotmuchError, cls).__new__(cls) - subclass = cls.get_exc_subclass(status) # which class to use? - return subclass.__new__(subclass, *args, **kwargs) - - def __init__(self, status=None, message=None): - self.status = status - self.message = message - - def __unicode__(self): - if self.message is not None: - return self.message - elif self.status is not None: - return STATUS.status2str(self.status) - else: - return 'Unknown error' - - -# List of Subclassed exceptions that correspond to STATUS values and are -# subclasses of NotmuchError. -class OutOfMemoryError(NotmuchError): - status = STATUS.OUT_OF_MEMORY - - -class ReadOnlyDatabaseError(NotmuchError): - status = STATUS.READ_ONLY_DATABASE - - -class XapianError(NotmuchError): - status = STATUS.XAPIAN_EXCEPTION - - -class FileError(NotmuchError): - status = STATUS.FILE_ERROR - - -class FileNotEmailError(NotmuchError): - status = STATUS.FILE_NOT_EMAIL - - -class DuplicateMessageIdError(NotmuchError): - status = STATUS.DUPLICATE_MESSAGE_ID - - -class NullPointerError(NotmuchError): - status = STATUS.NULL_POINTER - - -class TagTooLongError(NotmuchError): - status = STATUS.TAG_TOO_LONG - - -class UnbalancedFreezeThawError(NotmuchError): - status = STATUS.UNBALANCED_FREEZE_THAW - - -class UnbalancedAtomicError(NotmuchError): - status = STATUS.UNBALANCED_ATOMIC - - -class NotInitializedError(NotmuchError): - """Derived from NotmuchError, this occurs if the underlying data - structure (e.g. database is not initialized (yet) or an iterator has - been exhausted. You can test for NotmuchError with .status = - STATUS.NOT_INITIALIZED""" - status = STATUS.NOT_INITIALIZED - - class NotmuchDatabaseS(Structure): pass NotmuchDatabaseP = POINTER(NotmuchDatabaseS) diff --git a/bindings/python/notmuch/message.py b/bindings/python/notmuch/message.py index d17b9bc..9eb4fee 100644 --- a/bindings/python/notmuch/message.py +++ b/bindings/python/notmuch/message.py @@ -26,15 +26,17 @@ from .globals import ( Enum, _str, Python3StringMixIn, - STATUS, - NotmuchError, - NullPointerError, - NotInitializedError, NotmuchTagsP, NotmuchMessageP, NotmuchMessagesP, NotmuchFilenamesP, ) +from .errors import ( + STATUS, + NotmuchError, + NullPointerError, + NotInitializedError, +) from .tag import Tags from .filenames import Filenames diff --git a/bindings/python/notmuch/messages.py b/bindings/python/notmuch/messages.py index 20d3632..d94f91b 100644 --- a/bindings/python/notmuch/messages.py +++ b/bindings/python/notmuch/messages.py @@ -20,12 +20,14 @@ Copyright 2010 Sebastian Spaeth ' from .globals import ( nmlib, - NullPointerError, - NotInitializedError, NotmuchTagsP, NotmuchMessageP, NotmuchMessagesP, ) +from .errors import ( + NullPointerError, + NotInitializedError, +) from .tag import Tags from .message import Message diff --git a/bindings/python/notmuch/query.py b/bindings/python/notmuch/query.py index fcd67e5..ddaf8e0 100644 --- a/bindings/python/notmuch/query.py +++ b/bindings/python/notmuch/query.py @@ -26,6 +26,8 @@ from notmuch.globals import ( NotmuchThreadsP, NotmuchDatabaseP, NotmuchMessagesP, +) +from .errors import ( NullPointerError, NotInitializedError, ) diff --git a/bindings/python/notmuch/tag.py b/bindings/python/notmuch/tag.py index 526e51c..711bf53 100644 --- a/bindings/python/notmuch/tag.py +++ b/bindings/python/notmuch/tag.py @@ -20,9 +20,11 @@ from ctypes import c_char_p from notmuch.globals import ( nmlib, Python3StringMixIn, + NotmuchTagsP, +) +from .errors import ( NullPointerError, NotInitializedError, - NotmuchTagsP, ) diff --git a/bindings/python/notmuch/thread.py b/bindings/python/notmuch/thread.py index 0dac522..a759c90 100644 --- a/bindings/python/notmuch/thread.py +++ b/bindings/python/notmuch/thread.py @@ -20,12 +20,14 @@ Copyright 2010 Sebastian Spaeth ' from ctypes import c_char_p, c_long, c_int from notmuch.globals import ( nmlib, - NullPointerError, - NotInitializedError, NotmuchThreadP, NotmuchMessagesP, NotmuchTagsP, ) +from .errors import ( + NullPointerError, + NotInitializedError, +) from .messages import Messages from notmuch.tag import Tags from datetime import date diff --git a/bindings/python/notmuch/threads.py b/bindings/python/notmuch/threads.py index 9d305e2..690206e 100644 --- a/bindings/python/notmuch/threads.py +++ b/bindings/python/notmuch/threads.py @@ -20,11 +20,13 @@ Copyright 2010 Sebastian Spaeth ' from notmuch.globals import ( nmlib, Python3StringMixIn, - NullPointerError, - NotInitializedError, NotmuchThreadP, NotmuchThreadsP, ) +from .errors import ( + NullPointerError, + NotInitializedError, +) from .thread import Thread class Threads(Python3StringMixIn): -- cgit v1.2.3 From 3a95f3fbc1602d612aec2b7f1095e40c95723aee Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Fri, 16 Mar 2012 13:56:32 +0100 Subject: python: fix signature of two wrapped libnotmuch functions Signed-off-by: Justus Winter <4winter@informatik.uni-hamburg.de> --- bindings/python/notmuch/directory.py | 2 +- bindings/python/notmuch/threads.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'bindings/python/notmuch/threads.py') diff --git a/bindings/python/notmuch/directory.py b/bindings/python/notmuch/directory.py index 0c5e015..284cbdc 100644 --- a/bindings/python/notmuch/directory.py +++ b/bindings/python/notmuch/directory.py @@ -177,7 +177,7 @@ class Directory(object): _destroy = nmlib.notmuch_directory_destroy _destroy.argtypes = [NotmuchDirectoryP] - _destroy.argtypes = None + _destroy.restype = None def __del__(self): """Close and free the Directory""" diff --git a/bindings/python/notmuch/threads.py b/bindings/python/notmuch/threads.py index 690206e..225f524 100644 --- a/bindings/python/notmuch/threads.py +++ b/bindings/python/notmuch/threads.py @@ -172,7 +172,7 @@ class Threads(Python3StringMixIn): _destroy = nmlib.notmuch_threads_destroy _destroy.argtypes = [NotmuchThreadsP] - _destroy.argtypes = None + _destroy.restype = None def __del__(self): """Close and free the notmuch Threads""" -- cgit v1.2.3 From 1f08664a6b8f7cba63f63855833f877b66bbbe05 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Sun, 29 Apr 2012 16:33:06 +0200 Subject: python: strip superfluous single quote from copyright notices Signed-off-by: Justus Winter <4winter@informatik.uni-hamburg.de> --- bindings/python/notmuch/database.py | 2 +- bindings/python/notmuch/directory.py | 2 +- bindings/python/notmuch/filenames.py | 2 +- bindings/python/notmuch/globals.py | 2 +- bindings/python/notmuch/message.py | 2 +- bindings/python/notmuch/messages.py | 2 +- bindings/python/notmuch/query.py | 2 +- bindings/python/notmuch/tag.py | 2 +- bindings/python/notmuch/thread.py | 2 +- bindings/python/notmuch/threads.py | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) (limited to 'bindings/python/notmuch/threads.py') diff --git a/bindings/python/notmuch/database.py b/bindings/python/notmuch/database.py index 268e952..0ac8b06 100644 --- a/bindings/python/notmuch/database.py +++ b/bindings/python/notmuch/database.py @@ -14,7 +14,7 @@ for more details. You should have received a copy of the GNU General Public License along with notmuch. If not, see . -Copyright 2010 Sebastian Spaeth ' +Copyright 2010 Sebastian Spaeth """ import os diff --git a/bindings/python/notmuch/directory.py b/bindings/python/notmuch/directory.py index 284cbdc..667d3a4 100644 --- a/bindings/python/notmuch/directory.py +++ b/bindings/python/notmuch/directory.py @@ -14,7 +14,7 @@ for more details. You should have received a copy of the GNU General Public License along with notmuch. If not, see . -Copyright 2010 Sebastian Spaeth ' +Copyright 2010 Sebastian Spaeth """ from ctypes import c_uint, c_long diff --git a/bindings/python/notmuch/filenames.py b/bindings/python/notmuch/filenames.py index 12050df..f3d761d 100644 --- a/bindings/python/notmuch/filenames.py +++ b/bindings/python/notmuch/filenames.py @@ -14,7 +14,7 @@ for more details. You should have received a copy of the GNU General Public License along with notmuch. If not, see . -Copyright 2010 Sebastian Spaeth ' +Copyright 2010 Sebastian Spaeth """ from ctypes import c_char_p from notmuch.globals import ( diff --git a/bindings/python/notmuch/globals.py b/bindings/python/notmuch/globals.py index 442f3e3..823c3e2 100644 --- a/bindings/python/notmuch/globals.py +++ b/bindings/python/notmuch/globals.py @@ -14,7 +14,7 @@ for more details. You should have received a copy of the GNU General Public License along with notmuch. If not, see . -Copyright 2010 Sebastian Spaeth ' +Copyright 2010 Sebastian Spaeth """ import sys from ctypes import CDLL, Structure, POINTER diff --git a/bindings/python/notmuch/message.py b/bindings/python/notmuch/message.py index 9eb4fee..f1faf1d 100644 --- a/bindings/python/notmuch/message.py +++ b/bindings/python/notmuch/message.py @@ -14,7 +14,7 @@ for more details. You should have received a copy of the GNU General Public License along with notmuch. If not, see . -Copyright 2010 Sebastian Spaeth ' +Copyright 2010 Sebastian Spaeth Jesse Rosenthal """ diff --git a/bindings/python/notmuch/messages.py b/bindings/python/notmuch/messages.py index d94f91b..6b024cb 100644 --- a/bindings/python/notmuch/messages.py +++ b/bindings/python/notmuch/messages.py @@ -14,7 +14,7 @@ for more details. You should have received a copy of the GNU General Public License along with notmuch. If not, see . -Copyright 2010 Sebastian Spaeth ' +Copyright 2010 Sebastian Spaeth Jesse Rosenthal """ diff --git a/bindings/python/notmuch/query.py b/bindings/python/notmuch/query.py index ddaf8e0..27bc4df 100644 --- a/bindings/python/notmuch/query.py +++ b/bindings/python/notmuch/query.py @@ -14,7 +14,7 @@ for more details. You should have received a copy of the GNU General Public License along with notmuch. If not, see . -Copyright 2010 Sebastian Spaeth ' +Copyright 2010 Sebastian Spaeth """ from ctypes import c_char_p, c_uint diff --git a/bindings/python/notmuch/tag.py b/bindings/python/notmuch/tag.py index 711bf53..9b18160 100644 --- a/bindings/python/notmuch/tag.py +++ b/bindings/python/notmuch/tag.py @@ -14,7 +14,7 @@ for more details. You should have received a copy of the GNU General Public License along with notmuch. If not, see . -Copyright 2010 Sebastian Spaeth ' +Copyright 2010 Sebastian Spaeth """ from ctypes import c_char_p from notmuch.globals import ( diff --git a/bindings/python/notmuch/thread.py b/bindings/python/notmuch/thread.py index a759c90..a47b209 100644 --- a/bindings/python/notmuch/thread.py +++ b/bindings/python/notmuch/thread.py @@ -14,7 +14,7 @@ for more details. You should have received a copy of the GNU General Public License along with notmuch. If not, see . -Copyright 2010 Sebastian Spaeth ' +Copyright 2010 Sebastian Spaeth """ from ctypes import c_char_p, c_long, c_int diff --git a/bindings/python/notmuch/threads.py b/bindings/python/notmuch/threads.py index 225f524..fb053f9 100644 --- a/bindings/python/notmuch/threads.py +++ b/bindings/python/notmuch/threads.py @@ -14,7 +14,7 @@ for more details. You should have received a copy of the GNU General Public License along with notmuch. If not, see . -Copyright 2010 Sebastian Spaeth ' +Copyright 2010 Sebastian Spaeth """ from notmuch.globals import ( -- cgit v1.2.3 From 162687a99e412098729d639ed7bc27f01372cb84 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Mon, 30 Apr 2012 18:52:35 +0200 Subject: python: fix NULL pointer tests Fix the NULL pointer tests in the destructors of all classes and Database.create. Signed-off-by: Justus Winter <4winter@informatik.uni-hamburg.de> --- bindings/python/notmuch/database.py | 2 +- bindings/python/notmuch/directory.py | 2 +- bindings/python/notmuch/filenames.py | 2 +- bindings/python/notmuch/message.py | 2 +- bindings/python/notmuch/messages.py | 2 +- bindings/python/notmuch/query.py | 2 +- bindings/python/notmuch/tag.py | 2 +- bindings/python/notmuch/thread.py | 2 +- bindings/python/notmuch/threads.py | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) (limited to 'bindings/python/notmuch/threads.py') diff --git a/bindings/python/notmuch/database.py b/bindings/python/notmuch/database.py index 0ac8b06..525f7c9 100644 --- a/bindings/python/notmuch/database.py +++ b/bindings/python/notmuch/database.py @@ -189,7 +189,7 @@ class Database(object): :raises: :exc:`NotmuchError` in case of any failure (possibly after printing an error message on stderr). """ - if self._db is not None: + if self._db: raise NotmuchError(message="Cannot create db, this Database() " "already has an open one.") diff --git a/bindings/python/notmuch/directory.py b/bindings/python/notmuch/directory.py index 667d3a4..ae115f8 100644 --- a/bindings/python/notmuch/directory.py +++ b/bindings/python/notmuch/directory.py @@ -181,5 +181,5 @@ class Directory(object): def __del__(self): """Close and free the Directory""" - if self._dir_p is not None: + if self._dir_p: self._destroy(self._dir_p) diff --git a/bindings/python/notmuch/filenames.py b/bindings/python/notmuch/filenames.py index d201ae2..a0b2956 100644 --- a/bindings/python/notmuch/filenames.py +++ b/bindings/python/notmuch/filenames.py @@ -128,7 +128,7 @@ class Filenames(Python3StringMixIn): def __del__(self): """Close and free the notmuch filenames""" - if self._files_p is not None: + if self._files_p: self._destroy(self._files_p) def __len__(self): diff --git a/bindings/python/notmuch/message.py b/bindings/python/notmuch/message.py index 54c4e4b..4ec5147 100644 --- a/bindings/python/notmuch/message.py +++ b/bindings/python/notmuch/message.py @@ -741,5 +741,5 @@ class Message(Python3StringMixIn): def __del__(self): """Close and free the notmuch Message""" - if self._msg is not None: + if self._msg: self._destroy(self._msg) diff --git a/bindings/python/notmuch/messages.py b/bindings/python/notmuch/messages.py index 6b024cb..251fa3a 100644 --- a/bindings/python/notmuch/messages.py +++ b/bindings/python/notmuch/messages.py @@ -184,7 +184,7 @@ class Messages(object): def __del__(self): """Close and free the notmuch Messages""" - if self._msgs is not None: + if self._msgs: self._destroy(self._msgs) def format_messages(self, format, indent=0, entire_thread=False): diff --git a/bindings/python/notmuch/query.py b/bindings/python/notmuch/query.py index 27bc4df..756e63b 100644 --- a/bindings/python/notmuch/query.py +++ b/bindings/python/notmuch/query.py @@ -203,5 +203,5 @@ class Query(object): def __del__(self): """Close and free the Query""" - if self._query is not None: + if self._query: self._destroy(self._query) diff --git a/bindings/python/notmuch/tag.py b/bindings/python/notmuch/tag.py index 9b18160..e059813 100644 --- a/bindings/python/notmuch/tag.py +++ b/bindings/python/notmuch/tag.py @@ -137,5 +137,5 @@ class Tags(Python3StringMixIn): def __del__(self): """Close and free the notmuch tags""" - if self._tags is not None: + if self._tags: self._destroy(self._tags) diff --git a/bindings/python/notmuch/thread.py b/bindings/python/notmuch/thread.py index a47b209..2f60d49 100644 --- a/bindings/python/notmuch/thread.py +++ b/bindings/python/notmuch/thread.py @@ -260,5 +260,5 @@ class Thread(object): def __del__(self): """Close and free the notmuch Thread""" - if self._thread is not None: + if self._thread: self._destroy(self._thread) diff --git a/bindings/python/notmuch/threads.py b/bindings/python/notmuch/threads.py index fb053f9..a644164 100644 --- a/bindings/python/notmuch/threads.py +++ b/bindings/python/notmuch/threads.py @@ -176,5 +176,5 @@ class Threads(Python3StringMixIn): def __del__(self): """Close and free the notmuch Threads""" - if self._threads is not None: + if self._threads: self._destroy(self._threads) -- cgit v1.2.3 From 7f74a400d197dac5cdf36960f68f63ce3eeff486 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Mon, 30 Apr 2012 19:12:36 +0200 Subject: python: cleanup the __nonzero__ implementations Cleanup the code, reword the docstring and use the same implementation in the Threads, Tags and Messages classes. __nonzero__ implements truth value testing. If __nonzero__ is not implemented, the python runtime would fall back to `len(..) > 0` thus exhausting the iterator. Signed-off-by: Justus Winter <4winter@informatik.uni-hamburg.de> --- bindings/python/notmuch/messages.py | 14 +++++++++----- bindings/python/notmuch/tag.py | 18 +++++++++--------- bindings/python/notmuch/threads.py | 21 +++++++++------------ 3 files changed, 27 insertions(+), 26 deletions(-) (limited to 'bindings/python/notmuch/threads.py') diff --git a/bindings/python/notmuch/messages.py b/bindings/python/notmuch/messages.py index 251fa3a..59ef40a 100644 --- a/bindings/python/notmuch/messages.py +++ b/bindings/python/notmuch/messages.py @@ -172,11 +172,15 @@ class Messages(object): next = __next__ # python2.x iterator protocol compatibility def __nonzero__(self): - """ - :return: True if there is at least one more thread in the - Iterator, False if not.""" - return self._msgs is not None and \ - self._valid(self._msgs) > 0 + ''' + Implement truth value testing. If __nonzero__ is not + implemented, the python runtime would fall back to `len(..) > + 0` thus exhausting the iterator. + + :returns: True if the wrapped iterator has at least one more object + left. + ''' + return self._msgs and self._valid(self._msgs) _destroy = nmlib.notmuch_messages_destroy _destroy.argtypes = [NotmuchMessagesP] diff --git a/bindings/python/notmuch/tag.py b/bindings/python/notmuch/tag.py index e059813..363c348 100644 --- a/bindings/python/notmuch/tag.py +++ b/bindings/python/notmuch/tag.py @@ -109,15 +109,15 @@ class Tags(Python3StringMixIn): next = __next__ # python2.x iterator protocol compatibility def __nonzero__(self): - """Implement bool(Tags) check that can be repeatedly used - - If __nonzero__ is not implemented, "if Tags()" - will implicitly call __len__, using up our iterator, so it is - important that this function is defined. - - :returns: True if the Tags() iterator has at least one more Tag - left.""" - return self._valid(self._tags) > 0 + ''' + Implement truth value testing. If __nonzero__ is not + implemented, the python runtime would fall back to `len(..) > + 0` thus exhausting the iterator. + + :returns: True if the wrapped iterator has at least one more object + left. + ''' + return self._tags and self._valid(self._tags) def __unicode__(self): """string representation of :class:`Tags`: a space separated list of tags diff --git a/bindings/python/notmuch/threads.py b/bindings/python/notmuch/threads.py index a644164..d2e0a91 100644 --- a/bindings/python/notmuch/threads.py +++ b/bindings/python/notmuch/threads.py @@ -157,18 +157,15 @@ class Threads(Python3StringMixIn): return i def __nonzero__(self): - """Check if :class:`Threads` contains at least one more valid thread - - The existence of this function makes 'if Threads: foo' work, as - that will implicitely call len() exhausting the iterator if - __nonzero__ does not exist. This function makes `bool(Threads())` - work repeatedly. - - :return: True if there is at least one more thread in the - Iterator, False if not. None on a "Out-of-memory" error. - """ - return self._threads is not None and \ - self._valid(self._threads) > 0 + ''' + Implement truth value testing. If __nonzero__ is not + implemented, the python runtime would fall back to `len(..) > + 0` thus exhausting the iterator. + + :returns: True if the wrapped iterator has at least one more object + left. + ''' + return self._threads and self._valid(self._threads) _destroy = nmlib.notmuch_threads_destroy _destroy.argtypes = [NotmuchThreadsP] -- cgit v1.2.3 From 05c3e83bd272635ecc5e86d767250de1eb680a09 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Thu, 17 May 2012 16:58:53 +0200 Subject: python: use relative imports Signed-off-by: Justus Winter <4winter@informatik.uni-hamburg.de> --- bindings/python/notmuch/database.py | 6 +++--- bindings/python/notmuch/directory.py | 2 +- bindings/python/notmuch/filenames.py | 2 +- bindings/python/notmuch/query.py | 2 +- bindings/python/notmuch/tag.py | 2 +- bindings/python/notmuch/thread.py | 4 ++-- bindings/python/notmuch/threads.py | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) (limited to 'bindings/python/notmuch/threads.py') diff --git a/bindings/python/notmuch/database.py b/bindings/python/notmuch/database.py index 797554d..fb4c929 100644 --- a/bindings/python/notmuch/database.py +++ b/bindings/python/notmuch/database.py @@ -20,7 +20,7 @@ Copyright 2010 Sebastian Spaeth import os import codecs from ctypes import c_char_p, c_void_p, c_uint, byref, POINTER -from notmuch.globals import ( +from .globals import ( nmlib, Enum, _str, @@ -37,8 +37,8 @@ from .errors import ( NotInitializedError, ReadOnlyDatabaseError, ) -from notmuch.message import Message -from notmuch.tag import Tags +from .message import Message +from .tag import Tags from .query import Query from .directory import Directory diff --git a/bindings/python/notmuch/directory.py b/bindings/python/notmuch/directory.py index ae115f8..3b0a525 100644 --- a/bindings/python/notmuch/directory.py +++ b/bindings/python/notmuch/directory.py @@ -18,7 +18,7 @@ Copyright 2010 Sebastian Spaeth """ from ctypes import c_uint, c_long -from notmuch.globals import ( +from .globals import ( nmlib, NotmuchDirectoryP, NotmuchFilenamesP diff --git a/bindings/python/notmuch/filenames.py b/bindings/python/notmuch/filenames.py index a0b2956..229f414 100644 --- a/bindings/python/notmuch/filenames.py +++ b/bindings/python/notmuch/filenames.py @@ -17,7 +17,7 @@ along with notmuch. If not, see . Copyright 2010 Sebastian Spaeth """ from ctypes import c_char_p -from notmuch.globals import ( +from .globals import ( nmlib, NotmuchMessageP, NotmuchFilenamesP, diff --git a/bindings/python/notmuch/query.py b/bindings/python/notmuch/query.py index 756e63b..4abba5b 100644 --- a/bindings/python/notmuch/query.py +++ b/bindings/python/notmuch/query.py @@ -18,7 +18,7 @@ Copyright 2010 Sebastian Spaeth """ from ctypes import c_char_p, c_uint -from notmuch.globals import ( +from .globals import ( nmlib, Enum, _str, diff --git a/bindings/python/notmuch/tag.py b/bindings/python/notmuch/tag.py index 363c348..1d52345 100644 --- a/bindings/python/notmuch/tag.py +++ b/bindings/python/notmuch/tag.py @@ -17,7 +17,7 @@ along with notmuch. If not, see . Copyright 2010 Sebastian Spaeth """ from ctypes import c_char_p -from notmuch.globals import ( +from .globals import ( nmlib, Python3StringMixIn, NotmuchTagsP, diff --git a/bindings/python/notmuch/thread.py b/bindings/python/notmuch/thread.py index 2f60d49..789f9a0 100644 --- a/bindings/python/notmuch/thread.py +++ b/bindings/python/notmuch/thread.py @@ -18,7 +18,7 @@ Copyright 2010 Sebastian Spaeth """ from ctypes import c_char_p, c_long, c_int -from notmuch.globals import ( +from .globals import ( nmlib, NotmuchThreadP, NotmuchMessagesP, @@ -29,7 +29,7 @@ from .errors import ( NotInitializedError, ) from .messages import Messages -from notmuch.tag import Tags +from .tag import Tags from datetime import date class Thread(object): diff --git a/bindings/python/notmuch/threads.py b/bindings/python/notmuch/threads.py index d2e0a91..f8ca34a 100644 --- a/bindings/python/notmuch/threads.py +++ b/bindings/python/notmuch/threads.py @@ -17,7 +17,7 @@ along with notmuch. If not, see . Copyright 2010 Sebastian Spaeth """ -from notmuch.globals import ( +from .globals import ( nmlib, Python3StringMixIn, NotmuchThreadP, -- cgit v1.2.3