* [PATCH 1/2] python: add classes to wrap all notmuch_*_t types @ 2011-10-09 22:12 Justus Winter 2011-10-09 22:12 ` [PATCH 2/2] python: annotate all calls into libnotmuch with types Justus Winter 2011-11-02 7:25 ` [PATCH 1/2] python: add classes to wrap all notmuch_*_t types Sebastian Spaeth 0 siblings, 2 replies; 23+ messages in thread From: Justus Winter @ 2011-10-09 22:12 UTC (permalink / raw) To: notmuch Signed-off-by: Justus Winter <4winter@informatik.uni-hamburg.de> --- bindings/python/notmuch/globals.py | 38 +++++++++++++++++++++++++++++++++++- 1 files changed, 37 insertions(+), 1 deletions(-) diff --git a/bindings/python/notmuch/globals.py b/bindings/python/notmuch/globals.py index de1db16..36354fc 100644 --- a/bindings/python/notmuch/globals.py +++ b/bindings/python/notmuch/globals.py @@ -17,7 +17,7 @@ along with notmuch. If not, see <http://www.gnu.org/licenses/>. Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>' """ -from ctypes import CDLL, c_char_p, c_int +from ctypes import CDLL, c_char_p, c_int, Structure, POINTER from ctypes.util import find_library #----------------------------------------------------------------------------- @@ -182,3 +182,39 @@ def _str(value): return value.encode('UTF-8') return value + +class NotmuchDatabaseS(Structure): + pass +NotmuchDatabaseP = POINTER(NotmuchDatabaseS) + +class NotmuchQueryS(Structure): + pass +NotmuchQueryP = POINTER(NotmuchQueryS) + +class NotmuchThreadsS(Structure): + pass +NotmuchThreadsP = POINTER(NotmuchThreadsS) + +class NotmuchThreadS(Structure): + pass +NotmuchThreadP = POINTER(NotmuchThreadS) + +class NotmuchMessagesS(Structure): + pass +NotmuchMessagesP = POINTER(NotmuchMessagesS) + +class NotmuchMessageS(Structure): + pass +NotmuchMessageP = POINTER(NotmuchMessageS) + +class NotmuchTagsS(Structure): + pass +NotmuchTagsP = POINTER(NotmuchTagsS) + +class NotmuchDirectoryS(Structure): + pass +NotmuchDirectoryP = POINTER(NotmuchDirectoryS) + +class NotmuchFilenamesS(Structure): + pass +NotmuchFilenamesP = POINTER(NotmuchFilenamesS) -- 1.7.6.3 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 2/2] python: annotate all calls into libnotmuch with types 2011-10-09 22:12 [PATCH 1/2] python: add classes to wrap all notmuch_*_t types Justus Winter @ 2011-10-09 22:12 ` Justus Winter 2011-12-06 10:46 ` Patrick Totzke 2011-11-02 7:25 ` [PATCH 1/2] python: add classes to wrap all notmuch_*_t types Sebastian Spaeth 1 sibling, 1 reply; 23+ messages in thread From: Justus Winter @ 2011-10-09 22:12 UTC (permalink / raw) To: notmuch Add type information to the ctypes._FuncPtr wrappers and use the wrapper classes instead of c_void_p for pointers to notmuch_*_t. This enables the ctypes library to type check parameters being handed to functions from the notmuch library. Signed-off-by: Justus Winter <4winter@informatik.uni-hamburg.de> --- bindings/python/notmuch/database.py | 127 ++++++++++++++++++++++++++-------- bindings/python/notmuch/filename.py | 22 +++++- bindings/python/notmuch/message.py | 91 ++++++++++++++++++++----- bindings/python/notmuch/tag.py | 23 +++++-- bindings/python/notmuch/thread.py | 63 +++++++++++++---- 5 files changed, 255 insertions(+), 71 deletions(-) diff --git a/bindings/python/notmuch/database.py b/bindings/python/notmuch/database.py index f4bc53e..25b4b1b 100644 --- a/bindings/python/notmuch/database.py +++ b/bindings/python/notmuch/database.py @@ -18,9 +18,11 @@ Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>' """ import os -from ctypes import c_int, c_char_p, c_void_p, c_uint, c_long, byref +from ctypes import c_int, c_char_p, c_void_p, c_uint, c_long, byref, POINTER from notmuch.globals import (nmlib, STATUS, NotmuchError, NotInitializedError, - NullPointerError, OutOfMemoryError, XapianError, Enum, _str) + NullPointerError, OutOfMemoryError, XapianError, Enum, _str, + NotmuchDatabaseP, NotmuchDirectoryP, NotmuchMessageP, NotmuchTagsP, + NotmuchQueryP, NotmuchMessagesP, NotmuchThreadsP, NotmuchFilenamesP) from notmuch.thread import Threads from notmuch.message import Messages, Message from notmuch.tag import Tags @@ -56,37 +58,48 @@ class Database(object): """notmuch_database_get_directory""" _get_directory = nmlib.notmuch_database_get_directory - _get_directory.restype = c_void_p + _get_directory.argtypes = [NotmuchDatabaseP, c_char_p] + _get_directory.restype = NotmuchDirectoryP """notmuch_database_get_path""" _get_path = nmlib.notmuch_database_get_path + _get_path.argtypes = [NotmuchDatabaseP] _get_path.restype = c_char_p """notmuch_database_get_version""" _get_version = nmlib.notmuch_database_get_version + _get_version.argtypes = [NotmuchDatabaseP] _get_version.restype = c_uint """notmuch_database_open""" _open = nmlib.notmuch_database_open - _open.restype = c_void_p + _open.argtypes = [c_char_p, c_uint] + _open.restype = NotmuchDatabaseP """notmuch_database_upgrade""" _upgrade = nmlib.notmuch_database_upgrade - _upgrade.argtypes = [c_void_p, c_void_p, c_void_p] + _upgrade.argtypes = [NotmuchDatabaseP, c_void_p, c_void_p] + _upgrade.restype = c_uint """ notmuch_database_find_message""" _find_message = nmlib.notmuch_database_find_message + _find_message.argtypes = [NotmuchDatabaseP, c_char_p, POINTER(NotmuchMessageP)] + _find_message.restype = c_uint """notmuch_database_find_message_by_filename""" _find_message_by_filename = nmlib.notmuch_database_find_message_by_filename + _find_message_by_filename.argtypes = [NotmuchDatabaseP, c_char_p, POINTER(NotmuchMessageP)] + _find_message_by_filename.restype = c_uint """notmuch_database_get_all_tags""" _get_all_tags = nmlib.notmuch_database_get_all_tags - _get_all_tags.restype = c_void_p + _get_all_tags.argtypes = [NotmuchDatabaseP] + _get_all_tags.restype = NotmuchTagsP """notmuch_database_create""" _create = nmlib.notmuch_database_create - _create.restype = c_void_p + _create.argtypes = [c_char_p] + _create.restype = NotmuchDatabaseP def __init__(self, path=None, create=False, mode=0): """If *path* is `None`, we will try to read a users notmuch @@ -186,6 +199,10 @@ class Database(object): self._assert_db_is_initialized() return Database._get_version(self._db) + _needs_upgrade = nmlib.notmuch_database_needs_upgrade + _needs_upgrade.argtypes = [NotmuchDatabaseP] + _needs_upgrade.restype = bool + def needs_upgrade(self): """Does this database need to be upgraded before writing to it? @@ -197,7 +214,7 @@ class Database(object): :returns: `True` or `False` """ self._assert_db_is_initialized() - return nmlib.notmuch_database_needs_upgrade(self._db) + return self._needs_upgrade(self._db) def upgrade(self): """Upgrades the current database @@ -219,6 +236,10 @@ class Database(object): #TODO: catch exceptions, document return values and etc return status + _begin_atomic = nmlib.notmuch_database_begin_atomic + _begin_atomic.argtypes = [NotmuchDatabaseP] + _begin_atomic.restype = c_uint + def begin_atomic(self): """Begin an atomic database operation @@ -236,11 +257,15 @@ class Database(object): *Added in notmuch 0.9*""" self._assert_db_is_initialized() - status = nmlib.notmuch_database_begin_atomic(self._db) + status = self._begin_atomic(self._db) if status != STATUS.SUCCESS: raise NotmuchError(status) return status + _end_atomic = nmlib.notmuch_database_end_atomic + _end_atomic.argtypes = [NotmuchDatabaseP] + _end_atomic.restype = c_uint + def end_atomic(self): """Indicate the end of an atomic database operation @@ -258,7 +283,7 @@ class Database(object): *Added in notmuch 0.9*""" self._assert_db_is_initialized() - status = nmlib.notmuch_database_end_atomic(self._db) + status = self._end_atomic(self._db) if status != STATUS.SUCCESS: raise NotmuchError(status) return status @@ -299,6 +324,10 @@ class Database(object): # return the Directory, init it with the absolute path return Directory(_str(abs_dirpath), dir_p, self) + _add_message = nmlib.notmuch_database_add_message + _add_message.argtypes = [NotmuchDatabaseP, c_char_p, POINTER(NotmuchMessageP)] + _add_message.restype = c_uint + def add_message(self, filename, sync_maildir_flags=False): """Adds a new message to the database @@ -350,9 +379,7 @@ class Database(object): """ self._assert_db_is_initialized() msg_p = c_void_p() - status = nmlib.notmuch_database_add_message(self._db, - _str(filename), - byref(msg_p)) + status = self._add_message(self._db, _str(filename), byref(msg_p)) if not status in [STATUS.SUCCESS, STATUS.DUPLICATE_MESSAGE_ID]: raise NotmuchError(status) @@ -364,6 +391,10 @@ class Database(object): msg.maildir_flags_to_tags() return (msg, status) + _remove_message = nmlib.notmuch_database_remove_message + _remove_message.argtypes = [NotmuchDatabaseP, c_char_p] + _remove_message.restype = c_uint + def remove_message(self, filename): """Removes a message (filename) from the given notmuch database @@ -392,8 +423,7 @@ class Database(object): removed. """ self._assert_db_is_initialized() - return nmlib.notmuch_database_remove_message(self._db, - filename) + return self._remove_message(self._db, filename) def find_message(self, msgid): """Returns a :class:`Message` as identified by its message ID @@ -491,10 +521,14 @@ class Database(object): def __repr__(self): return "'Notmuch DB " + self.get_path() + "'" + _close = nmlib.notmuch_database_close + _close.argtypes = [NotmuchDatabaseP] + _close.restype = None + def __del__(self): """Close and free the notmuch database if needed""" if self._db is not None: - nmlib.notmuch_database_close(self._db) + self._close(self._db) def _get_user_default_db(self): """ Reads a user's notmuch config and returns his db location @@ -545,18 +579,22 @@ class Query(object): """notmuch_query_create""" _create = nmlib.notmuch_query_create - _create.restype = c_void_p + _create.argtypes = [NotmuchDatabaseP, c_char_p] + _create.restype = NotmuchQueryP """notmuch_query_search_threads""" _search_threads = nmlib.notmuch_query_search_threads - _search_threads.restype = c_void_p + _search_threads.argtypes = [NotmuchQueryP] + _search_threads.restype = NotmuchThreadsP """notmuch_query_search_messages""" _search_messages = nmlib.notmuch_query_search_messages - _search_messages.restype = c_void_p + _search_messages.argtypes = [NotmuchQueryP] + _search_messages.restype = NotmuchMessagesP """notmuch_query_count_messages""" _count_messages = nmlib.notmuch_query_count_messages + _count_messages.argtypes = [NotmuchQueryP] _count_messages.restype = c_uint def __init__(self, db, querystr): @@ -602,6 +640,10 @@ class Query(object): raise NullPointerError self._query = query_p + _set_sort = nmlib.notmuch_query_set_sort + _set_sort.argtypes = [NotmuchQueryP, c_uint] + _set_sort.argtypes = None + def set_sort(self, sort): """Set the sort order future results will be delivered in @@ -609,7 +651,7 @@ class Query(object): """ self._assert_query_is_initialized() self.sort = sort - nmlib.notmuch_query_set_sort(self._query, sort) + self._set_sort(self._query, sort) def search_threads(self): """Execute a query for threads @@ -661,10 +703,14 @@ class Query(object): self._assert_query_is_initialized() return Query._count_messages(self._query) + _destroy = nmlib.notmuch_query_destroy + _destroy.argtypes = [NotmuchQueryP] + _destroy.restype = None + def __del__(self): """Close and free the Query""" if self._query is not None: - nmlib.notmuch_query_destroy(self._query) + self._destroy(self._query) class Directory(object): @@ -683,19 +729,23 @@ class Directory(object): """notmuch_directory_get_mtime""" _get_mtime = nmlib.notmuch_directory_get_mtime + _get_mtime.argtypes = [NotmuchDirectoryP] _get_mtime.restype = c_long """notmuch_directory_set_mtime""" _set_mtime = nmlib.notmuch_directory_set_mtime - _set_mtime.argtypes = [c_char_p, c_long] + _set_mtime.argtypes = [NotmuchDirectoryP, c_long] + _set_mtime.restype = c_uint """notmuch_directory_get_child_files""" _get_child_files = nmlib.notmuch_directory_get_child_files - _get_child_files.restype = c_void_p + _get_child_files.argtypes = [NotmuchDirectoryP] + _get_child_files.restype = NotmuchFilenamesP """notmuch_directory_get_child_directories""" _get_child_directories = nmlib.notmuch_directory_get_child_directories - _get_child_directories.restype = c_void_p + _get_child_directories.argtypes = [NotmuchDirectoryP] + _get_child_directories.restype = NotmuchFilenamesP def _assert_dir_is_initialized(self): """Raises a NotmuchError(:attr:`STATUS`.NOT_INITIALIZED) if dir_p is None""" @@ -815,10 +865,14 @@ class Directory(object): """Object representation""" return "<notmuch Directory object '%s'>" % self._path + _destroy = nmlib.notmuch_directory_destroy + _destroy.argtypes = [NotmuchDirectoryP] + _destroy.argtypes = None + def __del__(self): """Close and free the Directory""" if self._dir_p is not None: - nmlib.notmuch_directory_destroy(self._dir_p) + self._destroy(self._dir_p) class Filenames(object): @@ -826,6 +880,7 @@ class Filenames(object): #notmuch_filenames_get _get = nmlib.notmuch_filenames_get + _get.argtypes = [NotmuchFilenamesP] _get.restype = c_char_p def __init__(self, files_p, parent): @@ -844,16 +899,24 @@ class Filenames(object): """ Make Filenames an iterator """ return self + _valid = nmlib.notmuch_filenames_valid + _valid.argtypes = [NotmuchFilenamesP] + _valid.restype = bool + + _move_to_next = nmlib.notmuch_filenames_move_to_next + _move_to_next.argtypes = [NotmuchFilenamesP] + _move_to_next.restype = None + def next(self): if self._files_p is None: raise NotmuchError(STATUS.NOT_INITIALIZED) - if not nmlib.notmuch_filenames_valid(self._files_p): + if not self._valid(self._files_p): self._files_p = None raise StopIteration file = Filenames._get(self._files_p) - nmlib.notmuch_filenames_move_to_next(self._files_p) + self._move_to_next(self._files_p) return file def __len__(self): @@ -872,13 +935,17 @@ class Filenames(object): raise NotmuchError(STATUS.NOT_INITIALIZED) i = 0 - while nmlib.notmuch_filenames_valid(self._files_p): - nmlib.notmuch_filenames_move_to_next(self._files_p) + while self._valid(self._files_p): + self._move_to_next(self._files_p) i += 1 self._files_p = None return i + _destroy = nmlib.notmuch_filenames_destroy + _destroy.argtypes = [NotmuchFilenamesP] + _destroy.restype = None + def __del__(self): """Close and free Filenames""" if self._files_p is not None: - nmlib.notmuch_filenames_destroy(self._files_p) + self._destroy(self._files_p) diff --git a/bindings/python/notmuch/filename.py b/bindings/python/notmuch/filename.py index de4d785..077754e 100644 --- a/bindings/python/notmuch/filename.py +++ b/bindings/python/notmuch/filename.py @@ -17,7 +17,8 @@ along with notmuch. If not, see <http://www.gnu.org/licenses/>. Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>' """ from ctypes import c_char_p -from notmuch.globals import nmlib, STATUS, NotmuchError +from notmuch.globals import (nmlib, STATUS, NotmuchError, + NotmuchFilenamesP, NotmuchMessagesP, NotmuchMessageP) class Filenames(object): @@ -50,6 +51,7 @@ class Filenames(object): #notmuch_filenames_get _get = nmlib.notmuch_filenames_get + _get.argtypes = [NotmuchFilenamesP] _get.restype = c_char_p def __init__(self, files_p, parent): @@ -74,6 +76,14 @@ class Filenames(object): #save reference to parent object so we keep it alive self._parent = parent + _valid = nmlib.notmuch_filenames_valid + _valid.argtypes = [NotmuchFilenamesP] + _valid.restype = bool + + _move_to_next = nmlib.notmuch_filenames_move_to_next + _move_to_next.argtypes = [NotmuchFilenamesP] + _move_to_next.restype = None + def as_generator(self): """Return generator of Filenames @@ -82,9 +92,9 @@ class Filenames(object): if self._files is None: raise NotmuchError(STATUS.NOT_INITIALIZED) - while nmlib.notmuch_filenames_valid(self._files): + while self._valid(self._files): yield Filenames._get(self._files) - nmlib.notmuch_filenames_move_to_next(self._files) + self._move_to_next(self._files) self._files = None @@ -101,7 +111,11 @@ class Filenames(object): """ return "\n".join(self) + _destroy = nmlib.notmuch_filenames_destroy + _destroy.argtypes = [NotmuchMessageP] + _destroy.restype = None + def __del__(self): """Close and free the notmuch filenames""" if self._files is not None: - nmlib.notmuch_filenames_destroy(self._files) + self._destroy(self._files) diff --git a/bindings/python/notmuch/message.py b/bindings/python/notmuch/message.py index 4bf90c2..e0c7eda 100644 --- a/bindings/python/notmuch/message.py +++ b/bindings/python/notmuch/message.py @@ -21,7 +21,8 @@ Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>' from ctypes import c_char_p, c_void_p, c_long, c_uint, c_int from datetime import date -from notmuch.globals import nmlib, STATUS, NotmuchError, Enum, _str +from notmuch.globals import (nmlib, STATUS, NotmuchError, Enum, _str, + NotmuchTagsP, NotmuchMessagesP, NotmuchMessageP, NotmuchFilenamesP) from notmuch.tag import Tags from notmuch.filename import Filenames import sys @@ -92,10 +93,12 @@ class Messages(object): #notmuch_messages_get _get = nmlib.notmuch_messages_get - _get.restype = c_void_p + _get.argtypes = [NotmuchMessagesP] + _get.restype = NotmuchMessageP _collect_tags = nmlib.notmuch_messages_collect_tags - _collect_tags.restype = c_void_p + _collect_tags.argtypes = [NotmuchMessagesP] + _collect_tags.restype = NotmuchTagsP def __init__(self, msgs_p, parent=None): """ @@ -146,16 +149,24 @@ class Messages(object): """ Make Messages an iterator """ return self + _valid = nmlib.notmuch_messages_valid + _valid.argtypes = [NotmuchMessagesP] + _valid.restype = bool + + _move_to_next = nmlib.notmuch_messages_move_to_next + _move_to_next.argtypes = [NotmuchMessagesP] + _move_to_next.restype = None + def next(self): if self._msgs is None: raise NotmuchError(STATUS.NOT_INITIALIZED) - if not nmlib.notmuch_messages_valid(self._msgs): + if not self._valid(self._msgs): self._msgs = None raise StopIteration msg = Message(Messages._get(self._msgs), self) - nmlib.notmuch_messages_move_to_next(self._msgs) + self._move_to_next(self._msgs) return msg def __nonzero__(self): @@ -163,12 +174,16 @@ class Messages(object): :return: True if there is at least one more thread in the Iterator, False if not.""" return self._msgs is not None and \ - nmlib.notmuch_messages_valid(self._msgs) > 0 + self._valid(self._msgs) > 0 + + _destroy = nmlib.notmuch_messages_destroy + _destroy.argtypes = [NotmuchMessagesP] + _destroy.restype = None def __del__(self): """Close and free the notmuch Messages""" if self._msgs is not None: - nmlib.notmuch_messages_destroy(self._msgs) + self._destroy(self._msgs) def print_messages(self, format, indent=0, entire_thread=False): """Outputs messages as needed for 'notmuch show' to sys.stdout @@ -235,44 +250,60 @@ class Message(object): """notmuch_message_get_filename (notmuch_message_t *message)""" _get_filename = nmlib.notmuch_message_get_filename + _get_filename.argtypes = [NotmuchMessageP] _get_filename.restype = c_char_p """return all filenames for a message""" _get_filenames = nmlib.notmuch_message_get_filenames - _get_filenames.restype = c_void_p + _get_filenames.argtypes = [NotmuchMessageP] + _get_filenames.restype = NotmuchFilenamesP """notmuch_message_get_flag""" _get_flag = nmlib.notmuch_message_get_flag - _get_flag.restype = c_uint + _get_flag.argtypes = [NotmuchMessageP, c_uint] + _get_flag.restype = bool + + """notmuch_message_set_flag""" + _set_flag = nmlib.notmuch_message_set_flag + _set_flag.argtypes = [NotmuchMessageP, c_uint, c_int] + _set_flag.restype = None """notmuch_message_get_message_id (notmuch_message_t *message)""" _get_message_id = nmlib.notmuch_message_get_message_id + _get_message_id.argtypes = [NotmuchMessageP] _get_message_id.restype = c_char_p """notmuch_message_get_thread_id""" _get_thread_id = nmlib.notmuch_message_get_thread_id + _get_thread_id.argtypes = [NotmuchMessageP] _get_thread_id.restype = c_char_p """notmuch_message_get_replies""" _get_replies = nmlib.notmuch_message_get_replies - _get_replies.restype = c_void_p + _get_replies.argtypes = [NotmuchMessageP] + _get_replies.restype = NotmuchMessagesP """notmuch_message_get_tags (notmuch_message_t *message)""" _get_tags = nmlib.notmuch_message_get_tags - _get_tags.restype = c_void_p + _get_tags.argtypes = [NotmuchMessageP] + _get_tags.restype = NotmuchTagsP _get_date = nmlib.notmuch_message_get_date + _get_date.argtypes = [NotmuchMessageP] _get_date.restype = c_long _get_header = nmlib.notmuch_message_get_header + _get_header.argtypes = [NotmuchMessageP, c_char_p] _get_header.restype = c_char_p """notmuch_status_t ..._maildir_flags_to_tags (notmuch_message_t *)""" _tags_to_maildir_flags = nmlib.notmuch_message_tags_to_maildir_flags + _tags_to_maildir_flags.argtypes = [NotmuchMessageP] _tags_to_maildir_flags.restype = c_int """notmuch_status_t ..._tags_to_maildir_flags (notmuch_message_t *)""" _maildir_flags_to_tags = nmlib.notmuch_message_maildir_flags_to_tags + _maildir_flags_to_tags.argtypes = [NotmuchMessageP] _maildir_flags_to_tags.restype = c_int #Constants: Flags that can be set/get with set_flag @@ -450,7 +481,7 @@ class Message(object): """ if self._msg is None: raise NotmuchError(STATUS.NOT_INITIALIZED) - nmlib.notmuch_message_set_flag(self._msg, flag, value) + self._set_flag(self._msg, flag, value) def get_tags(self): """Returns the message tags @@ -470,6 +501,10 @@ class Message(object): raise NotmuchError(STATUS.NULL_POINTER) return Tags(tags_p, self) + _add_tag = nmlib.notmuch_message_add_tag + _add_tag.argtypes = [NotmuchMessageP, c_char_p] + _add_tag.restype = c_uint + def add_tag(self, tag, sync_maildir_flags=False): """Adds a tag to the given message @@ -504,7 +539,7 @@ class Message(object): if self._msg is None: raise NotmuchError(STATUS.NOT_INITIALIZED) - status = nmlib.notmuch_message_add_tag(self._msg, _str(tag)) + status = self._add_tag(self._msg, _str(tag)) # bail out on failure if status != STATUS.SUCCESS: @@ -514,6 +549,10 @@ class Message(object): self.tags_to_maildir_flags() return STATUS.SUCCESS + _remove_tag = nmlib.notmuch_message_remove_tag + _remove_tag.argtypes = [NotmuchMessageP, c_char_p] + _remove_tag.restype = c_uint + def remove_tag(self, tag, sync_maildir_flags=False): """Removes a tag from the given message @@ -548,7 +587,7 @@ class Message(object): if self._msg is None: raise NotmuchError(STATUS.NOT_INITIALIZED) - status = nmlib.notmuch_message_remove_tag(self._msg, _str(tag)) + status = self._remove_tag(self._msg, _str(tag)) # bail out on error if status != STATUS.SUCCESS: raise NotmuchError(status) @@ -557,6 +596,10 @@ class Message(object): self.tags_to_maildir_flags() return STATUS.SUCCESS + _remove_all_tags = nmlib.notmuch_message_remove_all_tags + _remove_all_tags.argtypes = [NotmuchMessageP] + _remove_all_tags.restype = c_uint + def remove_all_tags(self, sync_maildir_flags=False): """Removes all tags from the given message. @@ -585,7 +628,7 @@ class Message(object): if self._msg is None: raise NotmuchError(STATUS.NOT_INITIALIZED) - status = nmlib.notmuch_message_remove_all_tags(self._msg) + status = self._remove_all_tags(self._msg) # bail out on error if status != STATUS.SUCCESS: @@ -595,6 +638,10 @@ class Message(object): self.tags_to_maildir_flags() return STATUS.SUCCESS + _freeze = nmlib.notmuch_message_freeze + _freeze.argtypes = [NotmuchMessageP] + _freeze.restype = c_uint + def freeze(self): """Freezes the current state of 'message' within the database @@ -639,7 +686,7 @@ class Message(object): if self._msg is None: raise NotmuchError(STATUS.NOT_INITIALIZED) - status = nmlib.notmuch_message_freeze(self._msg) + status = self._freeze(self._msg) if STATUS.SUCCESS == status: # return on success @@ -647,6 +694,10 @@ class Message(object): raise NotmuchError(status) + _thaw = nmlib.notmuch_message_thaw + _thaw.argtypes = [NotmuchMessageP] + _thaw.restype = c_uint + def thaw(self): """Thaws the current 'message' @@ -674,7 +725,7 @@ class Message(object): if self._msg is None: raise NotmuchError(STATUS.NOT_INITIALIZED) - status = nmlib.notmuch_message_thaw(self._msg) + status = self._thaw(self._msg) if STATUS.SUCCESS == status: # return on success @@ -896,7 +947,11 @@ class Message(object): res = cmp(list(self.get_filenames()), list(other.get_filenames())) return res + _destroy = nmlib.notmuch_message_destroy + _destroy.argtypes = [NotmuchMessageP] + _destroy.restype = None + def __del__(self): """Close and free the notmuch Message""" if self._msg is not None: - nmlib.notmuch_message_destroy(self._msg) + self._destroy(self._msg) diff --git a/bindings/python/notmuch/tag.py b/bindings/python/notmuch/tag.py index 50e3686..f3a3d27 100644 --- a/bindings/python/notmuch/tag.py +++ b/bindings/python/notmuch/tag.py @@ -17,7 +17,7 @@ along with notmuch. If not, see <http://www.gnu.org/licenses/>. Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>' """ from ctypes import c_char_p -from notmuch.globals import nmlib, STATUS, NotmuchError +from notmuch.globals import nmlib, STATUS, NotmuchError, NotmuchTagsP class Tags(object): @@ -50,6 +50,7 @@ class Tags(object): #notmuch_tags_get _get = nmlib.notmuch_tags_get + _get.argtypes = [NotmuchTagsP] _get.restype = c_char_p def __init__(self, tags_p, parent=None): @@ -80,14 +81,22 @@ class Tags(object): """ Make Tags an iterator """ return self + _valid = nmlib.notmuch_tags_valid + _valid.argtypes = [NotmuchTagsP] + _valid.restype = bool + + _move_to_next = nmlib.notmuch_tags_move_to_next + _move_to_next.argtypes = [NotmuchTagsP] + _move_to_next.restype = None + def next(self): if self._tags is None: raise NotmuchError(STATUS.NOT_INITIALIZED) - if not nmlib.notmuch_tags_valid(self._tags): + if not self._valid(self._tags): self._tags = None raise StopIteration tag = Tags._get(self._tags).decode('UTF-8') - nmlib.notmuch_tags_move_to_next(self._tags) + self._move_to_next(self._tags) return tag def __nonzero__(self): @@ -99,7 +108,7 @@ class Tags(object): :returns: True if the Tags() iterator has at least one more Tag left.""" - return nmlib.notmuch_tags_valid(self._tags) > 0 + return self._valid(self._tags) > 0 def __str__(self): """The str() representation of Tags() is a space separated list of tags @@ -112,7 +121,11 @@ class Tags(object): """ return " ".join(self) + _destroy = nmlib.notmuch_tags_destroy + _destroy.argtypes = [NotmuchTagsP] + _destroy.restype = None + def __del__(self): """Close and free the notmuch tags""" if self._tags is not None: - nmlib.notmuch_tags_destroy(self._tags) + self._destroy(self._tags) diff --git a/bindings/python/notmuch/thread.py b/bindings/python/notmuch/thread.py index 5e08eb3..d903c76 100644 --- a/bindings/python/notmuch/thread.py +++ b/bindings/python/notmuch/thread.py @@ -17,8 +17,10 @@ along with notmuch. If not, see <http://www.gnu.org/licenses/>. Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>' """ -from ctypes import c_char_p, c_void_p, c_long -from notmuch.globals import nmlib, STATUS, NotmuchError +from ctypes import c_char_p, c_void_p, c_long, c_int +from notmuch.globals import (nmlib, STATUS, + NotmuchError, NotmuchThreadP, NotmuchThreadsP, NotmuchMessagesP, + NotmuchTagsP,) from notmuch.message import Messages from notmuch.tag import Tags from datetime import date @@ -75,7 +77,8 @@ class Threads(object): #notmuch_threads_get _get = nmlib.notmuch_threads_get - _get.restype = c_void_p + _get.argtypes = [NotmuchThreadsP] + _get.restype = NotmuchThreadP def __init__(self, threads_p, parent=None): """ @@ -105,16 +108,24 @@ class Threads(object): """ 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 self._threads is None: raise NotmuchError(STATUS.NOT_INITIALIZED) - if not nmlib.notmuch_threads_valid(self._threads): + if not self._valid(self._threads): self._threads = None raise StopIteration thread = Thread(Threads._get(self._threads), self) - nmlib.notmuch_threads_move_to_next(self._threads) + self._move_to_next(self._threads) return thread def __len__(self): @@ -134,8 +145,8 @@ class Threads(object): i = 0 # returns 'bool'. On out-of-memory it returns None - while nmlib.notmuch_threads_valid(self._threads): - nmlib.notmuch_threads_move_to_next(self._threads) + while self._valid(self._threads): + self._move_to_next(self._threads) i += 1 # reset self._threads to mark as "exhausted" self._threads = None @@ -153,12 +164,16 @@ class Threads(object): Iterator, False if not. None on a "Out-of-memory" error. """ return self._threads is not None and \ - nmlib.notmuch_threads_valid(self._threads) > 0 + 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: - nmlib.notmuch_messages_destroy(self._threads) + self._destroy(self._threads) class Thread(object): @@ -166,29 +181,36 @@ class Thread(object): """notmuch_thread_get_thread_id""" _get_thread_id = nmlib.notmuch_thread_get_thread_id + _get_thread_id.argtypes = [NotmuchThreadP] _get_thread_id.restype = c_char_p """notmuch_thread_get_authors""" _get_authors = nmlib.notmuch_thread_get_authors + _get_authors.argtypes = [NotmuchThreadP] _get_authors.restype = c_char_p """notmuch_thread_get_subject""" _get_subject = nmlib.notmuch_thread_get_subject + _get_subject.argtypes = [NotmuchThreadP] _get_subject.restype = c_char_p """notmuch_thread_get_toplevel_messages""" _get_toplevel_messages = nmlib.notmuch_thread_get_toplevel_messages - _get_toplevel_messages.restype = c_void_p + _get_toplevel_messages.argtypes = [NotmuchThreadP] + _get_toplevel_messages.restype = NotmuchMessagesP _get_newest_date = nmlib.notmuch_thread_get_newest_date + _get_newest_date.argtypes = [NotmuchThreadP] _get_newest_date.restype = c_long _get_oldest_date = nmlib.notmuch_thread_get_oldest_date + _get_oldest_date.argtypes = [NotmuchThreadP] _get_oldest_date.restype = c_long """notmuch_thread_get_tags""" _get_tags = nmlib.notmuch_thread_get_tags - _get_tags.restype = c_void_p + _get_tags.argtypes = [NotmuchThreadP] + _get_tags.restype = NotmuchTagsP def __init__(self, thread_p, parent=None): """ @@ -225,6 +247,11 @@ class Thread(object): raise NotmuchError(STATUS.NOT_INITIALIZED) return Thread._get_thread_id(self._thread) + + _get_total_messages = nmlib.notmuch_thread_get_total_messages + _get_total_messages.argtypes = [NotmuchThreadP] + _get_total_messages.restype = c_int + def get_total_messages(self): """Get the total number of messages in 'thread' @@ -236,7 +263,7 @@ class Thread(object): """ if self._thread is None: raise NotmuchError(STATUS.NOT_INITIALIZED) - return nmlib.notmuch_thread_get_total_messages(self._thread) + return self._get_total_messages(self._thread) def get_toplevel_messages(self): """Returns a :class:`Messages` iterator for the top-level messages in @@ -267,6 +294,10 @@ class Thread(object): return Messages(msgs_p, self) + _get_matched_messages = nmlib.notmuch_thread_get_matched_messages + _get_matched_messages.argtypes = [NotmuchThreadP] + _get_matched_messages.restype = c_int + def get_matched_messages(self): """Returns the number of messages in 'thread' that matched the query @@ -278,7 +309,7 @@ class Thread(object): """ if self._thread is None: raise NotmuchError(STATUS.NOT_INITIALIZED) - return nmlib.notmuch_thread_get_matched_messages(self._thread) + return self._get_matched_messages(self._thread) def get_authors(self): """Returns the authors of 'thread' @@ -387,7 +418,11 @@ class Thread(object): thread['subject'], thread['tags']) + _destroy = nmlib.notmuch_thread_destroy + _destroy.argtypes = [NotmuchThreadP] + _destroy.restype = None + def __del__(self): """Close and free the notmuch Thread""" if self._thread is not None: - nmlib.notmuch_thread_destroy(self._thread) + self._destroy(self._thread) -- 1.7.6.3 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH 2/2] python: annotate all calls into libnotmuch with types 2011-10-09 22:12 ` [PATCH 2/2] python: annotate all calls into libnotmuch with types Justus Winter @ 2011-12-06 10:46 ` Patrick Totzke 2011-12-06 11:12 ` Sebastian Spaeth ` (2 more replies) 0 siblings, 3 replies; 23+ messages in thread From: Patrick Totzke @ 2011-12-06 10:46 UTC (permalink / raw) To: Justus Winter, notmuch This commit breaks raising XapianErrors for me. If I lock the index with some `notmuch tag +test '*'` and try to write to it in alot, i get a segfault and the following on stderr: Xapian exception occurred opening database: Unable to get write lock on /home/pazz/mail/.notmuch/xapian: already locked /p ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/2] python: annotate all calls into libnotmuch with types 2011-12-06 10:46 ` Patrick Totzke @ 2011-12-06 11:12 ` Sebastian Spaeth 2011-12-06 11:44 ` Patrick Totzke 2011-12-06 12:05 ` Sebastian Spaeth 2014-01-24 13:25 ` [PATCH 2/2] python: annotate all calls into libnotmuch with types David Bremner 2 siblings, 1 reply; 23+ messages in thread From: Sebastian Spaeth @ 2011-12-06 11:12 UTC (permalink / raw) To: Patrick Totzke, Justus Winter, notmuch [-- Attachment #1: Type: text/plain, Size: 652 bytes --] On Tue, 06 Dec 2011 10:46:31 +0000, Patrick Totzke <patricktotzke@googlemail.com> wrote: > This commit breaks raising XapianErrors for me. > > If I lock the index with some `notmuch tag +test '*'` > and try to write to it in alot, i get a segfault and > the following on stderr: > > Xapian exception occurred opening database: Unable to get write lock on > /home/pazz/mail/.notmuch/xapian: already locked Can you confirm that this only occurs with this patch and not without? To be honest, I don't see how the patch would change things in a way that make it throw XapianErrors that would not also occur before this patch. Sebastian [-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --] ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/2] python: annotate all calls into libnotmuch with types 2011-12-06 11:12 ` Sebastian Spaeth @ 2011-12-06 11:44 ` Patrick Totzke 0 siblings, 0 replies; 23+ messages in thread From: Patrick Totzke @ 2011-12-06 11:44 UTC (permalink / raw) To: Sebastian Spaeth, Justus Winter, notmuch [-- Attachment #1: Type: text/plain, Size: 1952 bytes --] yes, i can. here's how to reproduce it on master: fire a `notmuch tag +TEST1 '*'`, which should block the db for a while. Then use the attached script to write to the index (this could make a nice second testcase for the bindings in case the test body is large enough). On master, the script fails like this: A Xapian exception occurred opening database: Unable to get write lock on /home/pazz/mail/.notmuch/xapian: already locked Segmentation fault When you reset using `git reset e92b438f46a3a` (to 4winters first patch), the script fails like this, which is the intended behaviour: A Xapian exception occurred opening database: Unable to get write lock on /home/pazz/mail/.notmuch/xapian: already locked Traceback (most recent call last): File "./p.py", line 3, in <module> db = notmuch.Database(mode=notmuch.Database.MODE.READ_WRITE) File "/usr/local/lib/python2.7/dist-packages/notmuch/database.py", line 121, in __init__ self.open(path, mode) File "/usr/local/lib/python2.7/dist-packages/notmuch/database.py", line 173, in open raise NotmuchError(message="Could not open the specified database") notmuch.globals.NotmuchError: Could not open the specified database best, /p Quoting Sebastian Spaeth (2011-12-06 11:12:42) >On Tue, 06 Dec 2011 10:46:31 +0000, Patrick Totzke <patricktotzke@googlemail.com> wrote: >> This commit breaks raising XapianErrors for me. >> >> If I lock the index with some `notmuch tag +test '*'` >> and try to write to it in alot, i get a segfault and >> the following on stderr: >> >> Xapian exception occurred opening database: Unable to get write lock on >> /home/pazz/mail/.notmuch/xapian: already locked > >Can you confirm that this only occurs with this patch and not without? >To be honest, I don't see how the patch would change things in a way >that make it throw XapianErrors that would not also occur before this >patch. > >Sebastian [-- Attachment #2: exceptiontest.py --] [-- Type: text/x-python, Size: 181 bytes --] #!/usr/bin/python import notmuch db = notmuch.Database(mode=notmuch.Database.MODE.READ_WRITE) q_new = notmuch.Query(db, '*') for m in q_new.search_messages(): m.add_tag('TEST') ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/2] python: annotate all calls into libnotmuch with types 2011-12-06 10:46 ` Patrick Totzke 2011-12-06 11:12 ` Sebastian Spaeth @ 2011-12-06 12:05 ` Sebastian Spaeth [not found] ` <notmuch-sha1-f155d93e11888b35377531dd556b03fd493b7590> 2014-01-24 13:25 ` [PATCH 2/2] python: annotate all calls into libnotmuch with types David Bremner 2 siblings, 1 reply; 23+ messages in thread From: Sebastian Spaeth @ 2011-12-06 12:05 UTC (permalink / raw) To: Patrick Totzke, Justus Winter, notmuch [-- Attachment #1: Type: text/plain, Size: 954 bytes --] On Tue, 06 Dec 2011 10:46:31 +0000, Patrick Totzke <patricktotzke@googlemail.com> wrote: > This commit breaks raising XapianErrors for me. > > If I lock the index with some `notmuch tag +test '*'` > and try to write to it in alot, i get a segfault and > the following on stderr: > > Xapian exception occurred opening database: Unable to get write lock on > /home/pazz/mail/.notmuch/xapian: already locked Hi Justus, I can confirm that this patch breaks as Totzke has described it: http://git.notmuchmail.org/git/notmuch/commitdiff/3434d194026ff65217d9342ffe511f67fd71e79f This change makes python segfault with a Xapianerror on stdout rather than the python exception that we were seeing before this patch. - _open.restype = c_void_p + _open.restype = NotmuchDatabaseP As the patch obviously fixed other crashers I would like to not revert it. Can you have a look and see if you find a cause of that? Sebastian [-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --] ^ permalink raw reply [flat|nested] 23+ messages in thread
[parent not found: <notmuch-sha1-f155d93e11888b35377531dd556b03fd493b7590>]
* Re: [PATCH 2/2] python: annotate all calls into libnotmuch with types [not found] ` <notmuch-sha1-f155d93e11888b35377531dd556b03fd493b7590> @ 2011-12-07 18:49 ` Justus Winter [not found] ` <notmuch-sha1-c3821ec5e6ef2f83665b03ba10fdfff871f70c2b> 1 sibling, 0 replies; 23+ messages in thread From: Justus Winter @ 2011-12-07 18:49 UTC (permalink / raw) To: Sebastian Spaeth, notmuch [-- Attachment #1: Type: text/plain, Size: 2211 bytes --] Quoting Justus Winter (2011-12-06 13:51:08) >Quoting Sebastian Spaeth (2011-12-06 13:05:53) >>On Tue, 06 Dec 2011 10:46:31 +0000, Patrick Totzke <patricktotzke@googlemail.com> wrote: >>> This commit breaks raising XapianErrors for me. >>> >>> If I lock the index with some `notmuch tag +test '*'` >>> and try to write to it in alot, i get a segfault and >>> the following on stderr: >>> >>> Xapian exception occurred opening database: Unable to get write lock on >>> /home/pazz/mail/.notmuch/xapian: already locked >> >>Hi Justus, >>I can confirm that this patch breaks as Totzke has described it: >> >>http://git.notmuchmail.org/git/notmuch/commitdiff/3434d194026ff65217d9342ffe511f67fd71e79f >> >>This change makes python segfault with a Xapianerror on stdout rather >>than the python exception that we were seeing before this patch. >> >>- _open.restype = c_void_p >>+ _open.restype = NotmuchDatabaseP >> >> >>As the patch obviously fixed other crashers I would like to not revert >>it. Can you have a look and see if you find a cause of that? > >Yes, I've seen that one as well and could not figure out what causes >it since I thought that I wasn't changing the semantic of the binding. > >I began running alot in gdb since I get segfaults within libnotmuch >from time to time and managed to get a stack trace pointing to >notmuch_database_begin_atomic, but I couldn't figure out what caused >it. #0 0x00007f5f25e30f71 in notmuch_database_begin_atomic () from /home/teythoon/.local/lib/libnotmuch.so.2 #1 0x00007f5f2605ef70 in ffi_call_unix64 () from /usr/lib/python2.7/lib-dynload/_ctypes.so #2 0x00007f5f2605e9eb in ffi_call () from /usr/lib/python2.7/lib-dynload/_ctypes.so #3 0x00007f5f260529c7 in _call_function_pointer (argcount=1, resmem=0x7fff57659500, restype=<optimized out>, atypes=<optimized out>, avalues=0x7fff576594e0, pProc=0x7f5f25e30f70 <notmuch_database_begin_atomic>, flags=4353) at /home/packages/python/2.7/python2.7-2.7.2/Modules/_ctypes/callproc.c:827 with stderr saying: A Xapian exception occurred opening database: Unable to get write lock on /home/teythoon/Maildir/.notmuch/xapian: already locked Justus [-- Attachment #2: .signature --] [-- Type: application/octet-stream, Size: 17 bytes --] love u alot @,@ ^ permalink raw reply [flat|nested] 23+ messages in thread
[parent not found: <notmuch-sha1-c3821ec5e6ef2f83665b03ba10fdfff871f70c2b>]
* Re: [PATCH 2/2] python: annotate all calls into libnotmuch with types [not found] ` <notmuch-sha1-c3821ec5e6ef2f83665b03ba10fdfff871f70c2b> @ 2011-12-07 19:05 ` Justus Winter 2014-01-24 13:17 ` David Bremner 0 siblings, 1 reply; 23+ messages in thread From: Justus Winter @ 2011-12-07 19:05 UTC (permalink / raw) To: Justus Winter, Sebastian Spaeth, notmuch [-- Attachment #1: Type: text/plain, Size: 18321 bytes --] Quoting Justus Winter (2011-12-07 19:49:31) >Quoting Justus Winter (2011-12-06 13:51:08) >>I began running alot in gdb since I get segfaults within libnotmuch >>from time to time and managed to get a stack trace pointing to >>notmuch_database_begin_atomic, but I couldn't figure out what caused >>it. And another one: Reading symbols from /usr/bin/python...Reading symbols from /usr/lib/debug/usr/bin/python2.7...done. done. [New LWP 15188] [Thread debugging using libthread_db enabled] Core was generated by `/usr/bin/python /home/teythoon/.local/bin/afew -v --tag --new'. Program terminated with signal 6, Aborted. #0 0x00007f72f2cce405 in *__GI_raise (sig=<optimized out>) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64 in ../nptl/sysdeps/unix/sysv/linux/raise.c (gdb) bt #0 0x00007f72f2cce405 in *__GI_raise (sig=<optimized out>) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64 #1 0x00007f72f2cd1680 in *__GI_abort () at abort.c:92 #2 0x00007f72f1380bfd in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #3 0x00007f72f137eda6 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #4 0x00007f72f137edd3 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #5 0x00007f72f137eece in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #6 0x00007f72f16b792e in ChertTable::set_overwritten() const () from /usr/lib/libxapian.so.22 #7 0x00007f72f16ba7a6 in ChertTable::block_to_cursor(Cursor*, int, unsigned int) const () from /usr/lib/libxapian.so.22 #8 0x00007f72f16bcc35 in ChertTable::find(Cursor*) const () from /usr/lib/libxapian.so.22 #9 0x00007f72f1697431 in ChertCursor::find_entry(std::string const&) () from /usr/lib/libxapian.so.22 #10 0x00007f72f16c0858 in ?? () from /usr/lib/libxapian.so.22 #11 0x00007f72f16c0c69 in ?? () from /usr/lib/libxapian.so.22 #12 0x00007f72f16a649a in ?? () from /usr/lib/libxapian.so.22 #13 0x00007f72f1621001 in Xapian::Document::Internal::get_value(unsigned int) const () from /usr/lib/libxapian.so.22 #14 0x00007f72f162103c in Xapian::Document::get_value(unsigned int) const () from /usr/lib/libxapian.so.22 #15 0x00007f72f238ef23 in notmuch_message_get_header () from /home/teythoon/.local/lib/libnotmuch.so.2 #16 0x00007f72f25b7f70 in ffi_call_unix64 () from /usr/lib/python2.7/lib-dynload/_ctypes.so #17 0x00007f72f25b79eb in ffi_call () from /usr/lib/python2.7/lib-dynload/_ctypes.so #18 0x00007f72f25ab9c7 in _call_function_pointer (argcount=2, resmem=0x7fffc13a0310, restype=<optimized out>, atypes=<optimized out>, avalues=0x7fffc13a02f0, pProc=0x7f72f238ee50 <notmuch_message_get_header>, flags=4353) at /home/packages/python/2.7/python2.7-2.7.2/Modules/_ctypes/callproc.c:827 #19 _ctypes_callproc (pProc=0x7f72f238ee50 <notmuch_message_get_header>, argtuple=0x0, flags=4353, argtypes=<optimized out>, restype= <_ctypes.PyCSimpleType at remote 0xd17c30>, checker=0x0) at /home/packages/python/2.7/python2.7-2.7.2/Modules/_ctypes/callproc.c:1174 #20 0x00007f72f25a3257 in PyCFuncPtr_call (self=<optimized out>, inargs=<optimized out>, kwds=0x0) at /home/packages/python/2.7/python2.7-2.7.2/Modules/_ctypes/_ctypes.c:3913 #21 0x000000000041d35a in PyObject_Call (func=<_FuncPtr(__name__='notmuch_message_get_header') at remote 0xe02530>, arg=<optimized out>, kw=<optimized out>) at ../Objects/abstract.c:2529 #22 0x00000000004b9b4e in do_call (nk=<optimized out>, na=<optimized out>, pp_stack=0x7fffc13a05f0, func= <_FuncPtr(__name__='notmuch_message_get_header') at remote 0xe02530>) at ../Python/ceval.c:4239 #23 call_function (oparg=<optimized out>, pp_stack=0x7fffc13a05f0) at ../Python/ceval.c:4044 #24 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:2666 #25 0x00000000004b9d27 in fast_function (nk=<optimized out>, na=<optimized out>, n=<optimized out>, pp_stack=0x7fffc13a0730, func=<function at remote 0xdfef50>) at ../Python/ceval.c:4107 #26 call_function (oparg=<optimized out>, pp_stack=0x7fffc13a0730) at ../Python/ceval.c:4042 #27 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:2666 #28 0x00000000004bfc9d in PyEval_EvalCodeEx (co=0xcd28b0, globals=<optimized out>, locals=<optimized out>, args=<optimized out>, argcount=<optimized out>, kws=<optimized out>, kwcount=0, defs=0x0, defcount=0, closure=0x0) at ../Python/ceval.c:3253 #29 0x000000000044b36f in function_call (func=<function at remote 0xe03758>, arg= (<Message(_parent=<Messages(_parent=<Query(sort=None, _db=<Database(_db=<LP_NotmuchDatabaseS at remote 0xdf8e60>) at remote 0xe6c9d0>, _query=<LP_NotmuchQueryS at remote 0xdf8f80>) at remote 0xe6ca50>, _msgs=<LP_NotmuchMessagesS at remote 0xe770e0>) at remote 0xe6c990>, _msg=<LP_NotmuchMessageS at remote 0xe77200>) at remote 0x11a1b10>,), kw=0x0) at ../Objects/funcobject.c:526 #30 0x000000000041d35a in PyObject_Call (func=<function at remote 0xe03758>, arg=<optimized out>, kw=<optimized out>) at ../Objects/abstract.c:2529 #31 0x0000000000432bdb in instancemethod_call (func=<function at remote 0xe03758>, arg= (<Message(_parent=<Messages(_parent=<Query(sort=None, _db=<Database(_db=<LP_NotmuchDatabaseS at remote 0xdf8e60>) at remote 0xe6c9d0>, _query=<LP_NotmuchQueryS at remote 0xdf8f80>) at remote 0xe6ca50>, _msgs=<LP_NotmuchMessagesS at remote 0xe770e0>) at remote 0xe6c990>, _msg=<LP_NotmuchMessageS at remote 0xe77200>) at remote 0x11a1b10>,), kw=0x0) at ../Objects/classobject.c:2578 #32 0x000000000042668c in PyObject_Call (func=<instancemethod at remote 0x1192f00>, arg=<optimized out>, kw=0x0) at ../Objects/abstract.c:2529 #33 0x00000000004299fc in PyObject_CallFunctionObjArgs (callable=<instancemethod at remote 0x1192f00>) at ../Objects/abstract.c:2760 #34 0x0000000000466ebb in PyObject_Unicode (v= <Message(_parent=<Messages(_parent=<Query(sort=None, _db=<Database(_db=<LP_NotmuchDatabaseS at remote 0xdf8e60>) at remote 0xe6c9d0>, _query=<LP_NotmuchQueryS at remote 0xdf8f80>) at remote 0xe6ca50>, _msgs=<LP_NotmuchMessagesS at remote 0xe770e0>) at remote 0xe6c990>, _msg=<LP_NotmuchMessageS at remote 0xe77200>) at remote 0x11a1b10>) at ../Objects/object.c:509 #35 0x0000000000494443 in unicode_new (type=0x853200, args=<optimized out>, kwds=<optimized out>) at ../Objects/unicodeobject.c:8722 #36 0x000000000047ef15 in type_call (type=0x853200, args= (<Message(_parent=<Messages(_parent=<Query(sort=None, _db=<Database(_db=<LP_NotmuchDatabaseS at remote 0xdf8e60>) at remote 0xe6c9d0>, _query=<LP_NotmuchQueryS at remote 0xdf8f80>) at remote 0xe6ca50>, _msgs=<LP_NotmuchMessagesS at remote 0xe770e0>) at remote 0xe6c990>, _msg=<LP_NotmuchMessageS at remote 0xe77200>) at remote 0x11a1b10>,), kwds=0x0) at ../Objects/typeobject.c:721 #37 0x000000000041d35a in PyObject_Call (func=<type at remote 0x853200>, arg=<optimized out>, kw=<optimized out>) at ../Objects/abstract.c:2529 #38 0x00000000004b9b4e in do_call (nk=<optimized out>, na=<optimized out>, pp_stack=0x7fffc13a0e50, func=<type at remote 0x853200>) at ../Python/ceval.c:4239 #39 call_function (oparg=<optimized out>, pp_stack=0x7fffc13a0e50) at ../Python/ceval.c:4044 #40 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:2666 #41 0x00000000004bfc9d in PyEval_EvalCodeEx (co=0xcd2830, globals=<optimized out>, locals=<optimized out>, args=<optimized out>, argcount=<optimized out>, kws=<optimized out>, kwcount=0, defs=0x0, defcount=0, closure=0x0) at ../Python/ceval.c:3253 #42 0x000000000044b36f in function_call (func=<function at remote 0xe036e0>, arg= (<Message(_parent=<Messages(_parent=<Query(sort=None, _db=<Database(_db=<LP_NotmuchDatabaseS at remote 0xdf8e60>) at remote 0xe6c9d0>, _query=<LP_NotmuchQueryS at remote 0xdf8f80>) at remote 0xe6ca50>, _msgs=<LP_NotmuchMessagesS at remote 0xe770e0>) at remote 0xe6c990>, _msg=<LP_NotmuchMessageS at remote 0xe77200>) at remote 0x11a1b10>,), kw=0x0) at ../Objects/funcobject.c:526 #43 0x000000000041d35a in PyObject_Call (func=<function at remote 0xe036e0>, arg=<optimized out>, kw=<optimized out>) at ../Objects/abstract.c:2529 #44 0x0000000000432bdb in instancemethod_call (func=<function at remote 0xe036e0>, arg= (<Message(_parent=<Messages(_parent=<Query(sort=None, _db=<Database(_db=<LP_NotmuchDatabaseS at remote 0xdf8e60>) at remote 0xe6c9d0>, _query=<LP_NotmuchQueryS at remote 0xdf8f80>) at remote 0xe6ca50>, _msgs=<LP_NotmuchMessagesS at remote 0xe770e0>) at remote 0xe6c990>, _msg=<LP_NotmuchMessageS at remote 0xe77200>) at remote 0x11a1b10>,), kw=0x0) at ../Objects/classobject.c:2578 #45 0x000000000041d35a in PyObject_Call (func=<instancemethod at remote 0xe710a0>, arg=<optimized out>, kw=<optimized out>) at ../Objects/abstract.c:2529 #46 0x00000000004b8cb6 in PyEval_CallObjectWithKeywords (func=<instancemethod at remote 0xe710a0>, arg=(), kw=<optimized out>) at ../Python/ceval.c:3890 #47 0x00000000004837c9 in slot_tp_str (self= <Message(_parent=<Messages(_parent=<Query(sort=None, _db=<Database(_db=<LP_NotmuchDatabaseS at remote 0xdf8e60>) at remote 0xe6c9d0>, _query=<LP_NotmuchQueryS at remote 0xdf8f80>) at remote 0xe6ca50>, _msgs=<LP_NotmuchMessagesS at remote 0xe770e0>) at remote 0xe6c990>, _msg=<LP_NotmuchMessageS at remote 0xe77200>) at remote 0x11a1b10>) at ../Objects/typeobject.c:5341 #48 0x0000000000466848 in _PyObject_Str (v= <Message(_parent=<Messages(_parent=<Query(sort=None, _db=<Database(_db=<LP_NotmuchDatabaseS at remote 0xdf8e60>) at remote 0xe6c9d0>, _query=<LP_NotmuchQueryS at remote 0xdf8f80>) at remote 0xe6ca50>, _msgs=<LP_NotmuchMessagesS at remote 0xe770e0>) at remote 0xe6c990>, _msg=<LP_NotmuchMessageS at remote 0xe77200>) at remote 0x11a1b10>) at ../Objects/object.c:430 #49 0x0000000000471ce9 in PyString_Format (format='Adding tags %s to %s', args= ('juggling', <Message(_parent=<Messages(_parent=<Query(sort=None, _db=<Database(_db=<LP_NotmuchDatabaseS at remote 0xdf8e60>) at remote 0xe6c9d0>, _query=<LP_NotmuchQueryS at remote 0xdf8f80>) at remote 0xe6ca50>, _msgs=<LP_NotmuchMessagesS at remote 0xe770e0>) at remote 0xe6c990>, _msg=<LP_NotmuchMessageS at remote 0xe77200>) at remote 0x11a1b10>)) at ../Objects/stringobject.c:4435 #50 0x00000000004bad8d in PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:1308 #51 0x00000000004bfc9d in PyEval_EvalCodeEx (co=0xbdf930, globals=<optimized out>, locals=<optimized out>, args=<optimized out>, argcount=<optimized out>, kws=<optimized out>, kwcount=0, defs=0x0, defcount=0, closure=0x0) at ../Python/ceval.c:3253 #52 0x00000000004b9a03 in fast_function (nk=<optimized out>, na=3, n=<optimized out>, pp_stack=0x7fffc13a17c0, func=<function at remote 0xe3b9b0>) at ../Python/ceval.c:4117 #53 call_function (oparg=<optimized out>, pp_stack=0x7fffc13a17c0) at ../Python/ceval.c:4042 #54 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:2666 #55 0x00000000004b9d27 in fast_function (nk=<optimized out>, na=<optimized out>, n=<optimized out>, pp_stack=0x7fffc13a1900, func=<function at remote 0xe65f50>) at ../Python/ceval.c:4107 #56 call_function (oparg=<optimized out>, pp_stack=0x7fffc13a1900) at ../Python/ceval.c:4042 #57 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:2666 #58 0x00000000004b9d27 in fast_function (nk=<optimized out>, na=<optimized out>, n=<optimized out>, pp_stack=0x7fffc13a1a40, func=<function at remote 0xe3b8c0>) at ../Python/ceval.c:4107 #59 call_function (oparg=<optimized out>, pp_stack=0x7fffc13a1a40) at ../Python/ceval.c:4042 #60 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:2666 #61 0x00000000004c0295 in PyEval_EvalCodeEx (co=0xe44730, globals=<optimized out>, locals=<optimized out>, args=<optimized out>, argcount=<optimized out>, kws=<optimized out>, kwcount=0, defs=0x0, defcount=0, closure=0x0) at ../Python/ceval.c:3253 #62 0x00000000004b9a03 in fast_function (nk=<optimized out>, na=2, n=<optimized out>, pp_stack=0x7fffc13a1c30, func=<function at remote 0xe70aa0>) at ../Python/ceval.c:4117 #63 call_function (oparg=<optimized out>, pp_stack=0x7fffc13a1c30) at ../Python/ceval.c:4042 #64 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:2666 #65 0x00000000004bfc9d in PyEval_EvalCodeEx (co=0xb4a8b0, globals=<optimized out>, locals=<optimized out>, args=<optimized out>, argcount=<optimized out>, kws=<optimized out>, kwcount=0, defs=0x0, defcount=0, closure=0x0) at ../Python/ceval.c:3253 #66 0x00000000004c0772 in PyEval_EvalCode (co=<optimized out>, globals=<optimized out>, locals=<optimized out>) at ../Python/ceval.c:667 #67 0x00000000004dfa22 in run_mod (mod=<optimized out>, filename=<optimized out>, globals= {'no_actions': 1, 'configured_filter_chain': [<SpamFilter(_remove_tags={}, _tag_blacklist=set([]), spam_tag='spam', _flush_tags=[], _tags_to_remove=[], _add_tags={}, _tags_to_add=[], db_path='/home/teythoon/Maildir') at remote 0xe6c6d0>, <ClassifyingFilter(_remove_tags={}, _tag_blacklist=set([]), _flush_tags=[], _tags_to_remove=[], _add_tags={'003f01ccb4fb$902a6430$b07f2c90$@gmx.de': set([u'juggling']), '20111203042836.GI27538@rzssh1.informatik.uni-hamburg.de': set([u'juggling']), '4ED62052.4000109@informatik.uni-hamburg.de': set([u'juggling']), 'A106C811-6B91-4E70-938A-403C22F24DB4@mex21.net': set([u'juggling']), '4EDE321F.4040708@ramdrive.org': set([u'juggling']), 'CAC2-jLG5wauWYVhFwxX8Rh1sbexx4OT2sks7EbZRAWn9=hPs3w@mail.gmail.com': set([u'juggling']), '4ED65C2C.9070805@informatik.uni-hamburg.de': set([u'juggling']), '4EDCC624.3020509@informatik.uni-hamburg.de': set([u'juggling']), 'D51F629D-9742-4F0A-807E-A7CF8102C9BD@robert-marquardt.com': set([u'juggling']), '005601ccb50a$91845110$b48cf330$@gmx.de': set(...(truncated), locals= {'no_actions': 1, 'configured_filter_chain': [<SpamFilter(_remove_tags={}, _tag_blacklist=set([]), spam_tag='spam', _flush_tags=[], _tags_to_remove=[], _add_tags={}, _tags_to_add=[], db_path='/home/teythoon/Maildir') at remote 0xe6c6d0>, <ClassifyingFilter(_remove_tags={}, _tag_blacklist=set([]), _flush_tags=[], _tags_to_remove=[], _add_tags={'003f01ccb4fb$902a6430$b07f2c90$@gmx.de': set([u'juggling']), '20111203042836.GI27538@rzssh1.informatik.uni-hamburg.de': set([u'juggling']), '4ED62052.4000109@informatik.uni-hamburg.de': set([u'juggling']), 'A106C811-6B91-4E70-938A-403C22F24DB4@mex21.net': set([u'juggling']), '4EDE321F.4040708@ramdrive.org': set([u'juggling']), 'CAC2-jLG5wauWYVhFwxX8Rh1sbexx4OT2sks7EbZRAWn9=hPs3w@mail.gmail.com': set([u'juggling']), '4ED65C2C.9070805@informatik.uni-hamburg.de': set([u'juggling']), '4EDCC624.3020509@informatik.uni-hamburg.de': set([u'juggling']), 'D51F629D-9742-4F0A-807E-A7CF8102C9BD@robert-marquardt.com': set([u'juggling']), '005601ccb50a$91845110$b48cf330$@gmx.de': set(...(truncated), flags=<optimized out>, arena=<optimized out>) at ../Python/pythonrun.c:1346 #68 0x00000000004e05b4 in PyRun_FileExFlags (fp=0xb99c10, filename=0x7fffc13a3346 "/home/teythoon/.local/bin/afew", start=<optimized out>, globals= {'no_actions': 1, 'configured_filter_chain': [<SpamFilter(_remove_tags={}, _tag_blacklist=set([]), spam_tag='spam', _flush_tags=[], _tags_to_remove=[], _add_tags={}, _tags_to_add=[], db_path='/home/teythoon/Maildir') at remote 0xe6c6d0>, <ClassifyingFilter(_remove_tags={}, _tag_blacklist=set([]), _flush_tags=[], _tags_to_remove=[], _add_tags={'003f01ccb4fb$902a6430$b07f2c90$@gmx.de': set([u'juggling']), '20111203042836.GI27538@rzssh1.informatik.uni-hamburg.de': set([u'juggling']), '4ED62052.4000109@informatik.uni-hamburg.de': set([u'juggling']), 'A106C811-6B91-4E70-938A-403C22F24DB4@mex21.net': set([u'juggling']), '4EDE321F.4040708@ramdrive.org': set([u'juggling']), 'CAC2-jLG5wauWYVhFwxX8Rh1sbexx4OT2sks7EbZRAWn9=hPs3w@mail.gmail.com': set([u'juggling']), '4ED65C2C.9070805@informatik.uni-hamburg.de': set([u'juggling']), '4EDCC624.3020509@informatik.uni-hamburg.de': set([u'juggling']), 'D51F629D-9742-4F0A-807E-A7CF8102C9BD@robert-marquardt.com': set([u'juggling']), '005601ccb50a$91845110$b48cf330$@gmx.de': set(...(truncated), locals= {'no_actions': 1, 'configured_filter_chain': [<SpamFilter(_remove_tags={}, _tag_blacklist=set([]), spam_tag='spam', _flush_tags=[], _tags_to_remove=[], _add_tags={}, _tags_to_add=[], db_path='/home/teythoon/Maildir') at remote 0xe6c6d0>, <ClassifyingFilter(_remove_tags={}, _tag_blacklist=set([]), _flush_tags=[], _tags_to_remove=[], _add_tags={'003f01ccb4fb$902a6430$b07f2c90$@gmx.de': set([u'juggling']), '20111203042836.GI27538@rzssh1.informatik.uni-hamburg.de': set([u'juggling']), '4ED62052.4000109@informatik.uni-hamburg.de': set([u'juggling']), 'A106C811-6B91-4E70-938A-403C22F24DB4@mex21.net': set([u'juggling']), '4EDE321F.4040708@ramdrive.org': set([u'juggling']), 'CAC2-jLG5wauWYVhFwxX8Rh1sbexx4OT2sks7EbZRAWn9=hPs3w@mail.gmail.com': set([u'juggling']), '4ED65C2C.9070805@informatik.uni-hamburg.de': set([u'juggling']), '4EDCC624.3020509@informatik.uni-hamburg.de': set([u'juggling']), 'D51F629D-9742-4F0A-807E-A7CF8102C9BD@robert-marquardt.com': set([u'juggling']), '005601ccb50a$91845110$b48cf330$@gmx.de': set(...(truncated), closeit=1, flags=0x7fffc13a1f60) at ../Python/pythonrun.c:1332 #69 0x00000000004e10be in PyRun_SimpleFileExFlags (fp=0xb99c10, filename=<optimized out>, closeit=1, flags=0x7fffc13a1f60) at ../Python/pythonrun.c:936 #70 0x00000000004f10fd in Py_Main (argc=<optimized out>, argv=<optimized out>) at ../Modules/main.c:599 #71 0x00007f72f2cbaead in __libc_start_main (main=<optimized out>, argc=<optimized out>, ubp_av=<optimized out>, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffc13a2078) at libc-start.c:228 #72 0x000000000041f199 in _start () (gdb) q with stderr saying: terminate called after throwing an instance of 'Xapian::DatabaseModifiedError' Aborted (core dumped) This is an uncought c++ exception, right? If so I think it has to be cought somewhere in libnotmuch and turned into the appropriate error code (hm, there is only the generic XAPIAN_EXCEPTION, I thought there was a way to indicate that the db has been modified?). Justus [-- Attachment #2: .signature --] [-- Type: application/octet-stream, Size: 17 bytes --] love u alot @,@ ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/2] python: annotate all calls into libnotmuch with types 2011-12-07 19:05 ` Justus Winter @ 2014-01-24 13:17 ` David Bremner 2014-01-24 16:33 ` Justus Winter 0 siblings, 1 reply; 23+ messages in thread From: David Bremner @ 2014-01-24 13:17 UTC (permalink / raw) To: Justus Winter, notmuch Justus Winter <4winter@informatik.uni-hamburg.de> writes: > Quoting Justus Winter (2011-12-07 19:49:31) > And another one: [stack trace snipped] > #69 0x00000000004e10be in PyRun_SimpleFileExFlags (fp=0xb99c10, filename=<optimized out>, closeit=1, flags=0x7fffc13a1f60) at ../Python/pythonrun.c:936 > #70 0x00000000004f10fd in Py_Main (argc=<optimized out>, argv=<optimized out>) at ../Modules/main.c:599 > #71 0x00007f72f2cbaead in __libc_start_main (main=<optimized out>, argc=<optimized out>, ubp_av=<optimized out>, init=<optimized out>, fini=<optimized out>, > rtld_fini=<optimized out>, stack_end=0x7fffc13a2078) at libc-start.c:228 > #72 0x000000000041f199 in _start () > (gdb) q > > with stderr saying: > > terminate called after throwing an instance of 'Xapian::DatabaseModifiedError' > Aborted (core dumped) > > This is an uncought c++ exception, right? If so I think it has to be > cought somewhere in libnotmuch and turned into the appropriate error > code (hm, there is only the generic XAPIAN_EXCEPTION, I thought there > was a way to indicate that the db has been modified?). Can you still reproduce this bug? If so, a small test case (python is fine, but ideally not requiring afew) would be helpful. d ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/2] python: annotate all calls into libnotmuch with types 2014-01-24 13:17 ` David Bremner @ 2014-01-24 16:33 ` Justus Winter 2014-01-25 1:40 ` David Bremner 0 siblings, 1 reply; 23+ messages in thread From: Justus Winter @ 2014-01-24 16:33 UTC (permalink / raw) To: David Bremner, notmuch Hi :) Quoting David Bremner (2014-01-24 14:17:27) > Justus Winter <4winter@informatik.uni-hamburg.de> writes: > > > Quoting Justus Winter (2011-12-07 19:49:31) > > > And another one: > [stack trace snipped] > > #69 0x00000000004e10be in PyRun_SimpleFileExFlags (fp=0xb99c10, filename=<optimized out>, closeit=1, flags=0x7fffc13a1f60) at ../Python/pythonrun.c:936 > > #70 0x00000000004f10fd in Py_Main (argc=<optimized out>, argv=<optimized out>) at ../Modules/main.c:599 > > #71 0x00007f72f2cbaead in __libc_start_main (main=<optimized out>, argc=<optimized out>, ubp_av=<optimized out>, init=<optimized out>, fini=<optimized out>, > > rtld_fini=<optimized out>, stack_end=0x7fffc13a2078) at libc-start.c:228 > > #72 0x000000000041f199 in _start () > > (gdb) q > > > > with stderr saying: > > > > terminate called after throwing an instance of 'Xapian::DatabaseModifiedError' > > Aborted (core dumped) > > > > This is an uncought c++ exception, right? If so I think it has to be > > cought somewhere in libnotmuch and turned into the appropriate error > > code (hm, there is only the generic XAPIAN_EXCEPTION, I thought there > > was a way to indicate that the db has been modified?). > > Can you still reproduce this bug? If so, a small test case (python is > fine, but ideally not requiring afew) would be helpful. I'm sorry, I've no idea how to reproduce this. I have, however, some more test cases that crash libnotmuch, like this one: ~~~ snap ~~~ import os import notmuch db_path = os.path.expanduser('~/Maildir') db = notmuch.Database(db_path, mode=notmuch.Database.MODE.READ_WRITE) directory = db.get_directory(os.path.join(db_path, 'cur')) db._destroy(db._db) try: directory.get_child_files() except notmuch.errors.NotInitializedError as e: print('yeah') else: assert False, "Hey, where's my exception?" ~~~ snap ~~~ % python destroy_minimal.py [2] 3907 abort (core dumped) python destroy_minimal.py Program terminated with signal 6, Aborted. #0 0x00007f996ad021d5 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56 56 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory. (gdb) bt #0 0x00007f996ad021d5 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56 #1 0x00007f996ad05388 in __GI_abort () at abort.c:90 #2 0x00007f99699d4486 in talloc_abort (reason=0x7f99699db648 "Bad talloc magic value - access after free") at ../talloc.c:317 #3 0x00007f99699d8097 in talloc_abort_access_after_free () at ../talloc.c:336 #4 talloc_chunk_from_ptr (ptr=0x23e6f20) at ../talloc.c:357 #5 talloc_chunk_from_ptr (ptr=0x23e6f20) at ../talloc.c:2064 #6 __talloc (size=17, context=0x23e6f20) at ../talloc.c:555 #7 talloc_vasprintf (t=<optimized out>, fmt=0x7f996a3a56ef "%s%u:", ap=0x7fffb612bff8) at ../talloc.c:2079 #8 0x00007f99699d8167 in talloc_asprintf (t=<optimized out>, fmt=<optimized out>) at ../talloc.c:2101 #9 0x00007f996a39c02e in notmuch_directory_get_child_files () from /home/teythoon/.local/lib/libnotmuch.so.3 #10 0x00007f996a5b1cfc in ffi_call_unix64 () from /usr/lib/x86_64-linux-gnu/libffi.so.6 #11 0x00007f996a5b162c in ffi_call () from /usr/lib/x86_64-linux-gnu/libffi.so.6 #12 0x00007f996a7c86d0 in _ctypes_callproc () from /usr/lib/python2.7/lib-dynload/_ctypes.x86_64-linux-gnu.so #13 0x00007f996a7ca08e in PyCFuncPtr_call.3149.2622 () from /usr/lib/python2.7/lib-dynload/_ctypes.x86_64-linux-gnu.so #14 0x000000000055f47a in PyEval_EvalFrameEx () at ../Objects/abstract.c:2529 #15 0x000000000055f7ba in PyEval_EvalFrameEx () at ../Python/ceval.c:4107 #16 0x0000000000566bfb in PyEval_EvalCode () at ../Python/ceval.c:3253 #17 0x0000000000469499 in run_mod.42569 () at ../Python/pythonrun.c:1370 #18 0x0000000000469819 in PyRun_FileExFlags () at ../Python/pythonrun.c:1356 #19 0x0000000000469d52 in PyRun_SimpleFileExFlags () at ../Python/pythonrun.c:948 #20 0x000000000046b65f in Py_Main () at ../Modules/main.c:640 #21 0x00007f996acee995 in __libc_start_main (main=0x46b71d <main>, argc=2, ubp_av=0x7fffb612ca58, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffb612ca48) at libc-start.c:276 #22 0x0000000000573f2e in _start () This is a bit contrived b/c I'm destroying the db object by hand. Never the less libnotmuch calls abort, and there is no way to contain something like this in the python bindings. I've seen your recent proposal to improve the error reporting for libnotmuch functions. I think it's awesome, albeit a little late. I've no idea how other frontends deal with libnotmuch, but alot has moved libnotmuch to it's own process to contain any crashes (or libnotmuch calling exit(3)), and to prevent libnotmuch from writing to stderr destroying alots curses gui. I've always felt like libnotmuch users were second-class citizens, the primary target of libnotmuch being the notmuch binary. Justus ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/2] python: annotate all calls into libnotmuch with types 2014-01-24 16:33 ` Justus Winter @ 2014-01-25 1:40 ` David Bremner 2014-01-25 3:07 ` [PATCH] lib: update documentation for notmuch_database_get_directory David Bremner 0 siblings, 1 reply; 23+ messages in thread From: David Bremner @ 2014-01-25 1:40 UTC (permalink / raw) To: Justus Winter, notmuch Justus Winter <4winter@informatik.uni-hamburg.de> writes: > #0 0x00007f996ad021d5 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56 > 56 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory. > (gdb) bt > #0 0x00007f996ad021d5 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56 > #1 0x00007f996ad05388 in __GI_abort () at abort.c:90 > #2 0x00007f99699d4486 in talloc_abort (reason=0x7f99699db648 "Bad talloc magic value - access after free") at ../talloc.c:317 > #3 0x00007f99699d8097 in talloc_abort_access_after_free () at ../talloc.c:336 > This is a bit contrived b/c I'm destroying the db object by > hand. Never the less libnotmuch calls abort, and there is no way to > contain something like this in the python bindings. FWIW libnotmuch is not directly calling abort here, talloc is, because it is detecting illegal memory access patterns. So there could well be a libnotmuch bug here, but it isn't really related to error handling. As far as I can tell, the underlying reason for the crash is that that talloc is a hierarchical memory allocator, and the directory is a child of the database. This "ownership" should probably be documented in the header for notmuch_database_get_directory. This won't fix your crash, of course ;). d ^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH] lib: update documentation for notmuch_database_get_directory 2014-01-25 1:40 ` David Bremner @ 2014-01-25 3:07 ` David Bremner 2014-01-25 11:46 ` Tomi Ollila 2014-01-26 14:02 ` David Bremner 0 siblings, 2 replies; 23+ messages in thread From: David Bremner @ 2014-01-25 3:07 UTC (permalink / raw) To: notmuch Clarify that using the directory after destroying the corresponding database is not permitted. This is implicit in the description of notmuch_database_destroy, but it doesn't hurt to be explicit, and we do express similar "ownership" relationships at other places in the docs. --- lib/notmuch.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/notmuch.h b/lib/notmuch.h index 68896ae..3df1ade 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -415,6 +415,10 @@ notmuch_database_end_atomic (notmuch_database_t *notmuch); * If this directory object does not exist in the database, this * returns NOTMUCH_STATUS_SUCCESS and sets *directory to NULL. * + * Otherwise the returned directory object is owned by the database + * and as such, will only be valid until notmuch_database_destroy is + * called. + * * Return value: * * NOTMUCH_STATUS_SUCCESS: Successfully retrieved directory. -- 1.8.5.2 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH] lib: update documentation for notmuch_database_get_directory 2014-01-25 3:07 ` [PATCH] lib: update documentation for notmuch_database_get_directory David Bremner @ 2014-01-25 11:46 ` Tomi Ollila 2014-01-26 14:02 ` David Bremner 1 sibling, 0 replies; 23+ messages in thread From: Tomi Ollila @ 2014-01-25 11:46 UTC (permalink / raw) To: David Bremner, notmuch On Sat, Jan 25 2014, David Bremner <david@tethera.net> wrote: > Clarify that using the directory after destroying the corresponding > database is not permitted. > > This is implicit in the description of notmuch_database_destroy, but > it doesn't hurt to be explicit, and we do express similar "ownership" > relationships at other places in the docs. > --- LGTM. Tomi > lib/notmuch.h | 4 ++++ > 1 file changed, 4 insertions(+) > > diff --git a/lib/notmuch.h b/lib/notmuch.h > index 68896ae..3df1ade 100644 > --- a/lib/notmuch.h > +++ b/lib/notmuch.h > @@ -415,6 +415,10 @@ notmuch_database_end_atomic (notmuch_database_t *notmuch); > * If this directory object does not exist in the database, this > * returns NOTMUCH_STATUS_SUCCESS and sets *directory to NULL. > * > + * Otherwise the returned directory object is owned by the database > + * and as such, will only be valid until notmuch_database_destroy is > + * called. > + * > * Return value: > * > * NOTMUCH_STATUS_SUCCESS: Successfully retrieved directory. > -- > 1.8.5.2 > > _______________________________________________ > notmuch mailing list > notmuch@notmuchmail.org > http://notmuchmail.org/mailman/listinfo/notmuch ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] lib: update documentation for notmuch_database_get_directory 2014-01-25 3:07 ` [PATCH] lib: update documentation for notmuch_database_get_directory David Bremner 2014-01-25 11:46 ` Tomi Ollila @ 2014-01-26 14:02 ` David Bremner 1 sibling, 0 replies; 23+ messages in thread From: David Bremner @ 2014-01-26 14:02 UTC (permalink / raw) To: notmuch David Bremner <david@tethera.net> writes: > Clarify that using the directory after destroying the corresponding > database is not permitted. > > This is implicit in the description of notmuch_database_destroy, but > it doesn't hurt to be explicit, and we do express similar "ownership" > relationships at other places in the docs. pushed, d ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/2] python: annotate all calls into libnotmuch with types 2011-12-06 10:46 ` Patrick Totzke 2011-12-06 11:12 ` Sebastian Spaeth 2011-12-06 12:05 ` Sebastian Spaeth @ 2014-01-24 13:25 ` David Bremner 2 siblings, 0 replies; 23+ messages in thread From: David Bremner @ 2014-01-24 13:25 UTC (permalink / raw) To: Patrick Totzke, Justus Winter, notmuch Patrick Totzke <patricktotzke@googlemail.com> writes: > This commit breaks raising XapianErrors for me. > > If I lock the index with some `notmuch tag +test '*'` > and try to write to it in alot, i get a segfault and > the following on stderr: > > Xapian exception occurred opening database: Unable to get write lock on > /home/pazz/mail/.notmuch/xapian: already locked > > /p Is is this bug still reproducible with git master? If so, can you reproduce it purely with the CLI? It would be nice to narrow down if this a bug in the lib or in the bindings. d ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 1/2] python: add classes to wrap all notmuch_*_t types 2011-10-09 22:12 [PATCH 1/2] python: add classes to wrap all notmuch_*_t types Justus Winter 2011-10-09 22:12 ` [PATCH 2/2] python: annotate all calls into libnotmuch with types Justus Winter @ 2011-11-02 7:25 ` Sebastian Spaeth 2011-11-28 12:36 ` Justus Winter 1 sibling, 1 reply; 23+ messages in thread From: Sebastian Spaeth @ 2011-11-02 7:25 UTC (permalink / raw) To: Justus Winter, notmuch [-- Attachment #1: Type: text/plain, Size: 464 bytes --] On Mon, 10 Oct 2011 00:12:53 +0200, Justus Winter <4winter@informatik.uni-hamburg.de> wrote: > Signed-off-by: Justus Winter <4winter@informatik.uni-hamburg.de> > --- > bindings/python/notmuch/globals.py | 38 +++++++++++++++++++++++++++++++++++- Hi there, catching up on email, sorry for the delay. I am not opposed to the change, but I fail to see any justification for a whole lot more complexity either. What was wrong with the previous approach? Sebastian [-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --] ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 1/2] python: add classes to wrap all notmuch_*_t types 2011-11-02 7:25 ` [PATCH 1/2] python: add classes to wrap all notmuch_*_t types Sebastian Spaeth @ 2011-11-28 12:36 ` Justus Winter 2011-12-01 21:25 ` Sebastian Spaeth 0 siblings, 1 reply; 23+ messages in thread From: Justus Winter @ 2011-11-28 12:36 UTC (permalink / raw) To: Sebastian Spaeth, notmuch [-- Attachment #1: Type: text/plain, Size: 822 bytes --] Quoting Sebastian Spaeth (2011-11-02 08:25:53) >On Mon, 10 Oct 2011 00:12:53 +0200, Justus Winter <4winter@informatik.uni-hamburg.de> wrote: >> Signed-off-by: Justus Winter <4winter@informatik.uni-hamburg.de> >> --- >> bindings/python/notmuch/globals.py | 38 +++++++++++++++++++++++++++++++++++- > >Hi there, catching up on email, sorry for the delay. >I am not opposed to the change, but I fail to see any justification for >a whole lot more complexity either. What was wrong with the previous >approach? Well, quoting my commit message: > Add type information to the ctypes._FuncPtr wrappers and > use the wrapper classes instead of c_void_p for pointers > to notmuch_*_t. > > This enables the ctypes library to type check parameters > being handed to functions from the notmuch library. Justus [-- Attachment #2: .signature --] [-- Type: application/octet-stream, Size: 17 bytes --] love u alot @,@ ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 1/2] python: add classes to wrap all notmuch_*_t types 2011-11-28 12:36 ` Justus Winter @ 2011-12-01 21:25 ` Sebastian Spaeth 2011-12-01 23:32 ` James Westby 0 siblings, 1 reply; 23+ messages in thread From: Sebastian Spaeth @ 2011-12-01 21:25 UTC (permalink / raw) To: Justus Winter, notmuch [-- Attachment #1: Type: text/plain, Size: 449 bytes --] On Mon, 28 Nov 2011 13:36:44 +0100, Justus Winter wrote: > Well, quoting my commit message: > > > Add type information to the ctypes._FuncPtr wrappers and > > use the wrapper classes instead of c_void_p for pointers > > to notmuch_*_t. > > > > This enables the ctypes library to type check parameters > > being handed to functions from the notmuch library. This strikes me as a rather good thing, so the patches went in. Sebastian [-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --] ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 1/2] python: add classes to wrap all notmuch_*_t types 2011-12-01 21:25 ` Sebastian Spaeth @ 2011-12-01 23:32 ` James Westby 2011-12-02 12:35 ` Justus Winter 0 siblings, 1 reply; 23+ messages in thread From: James Westby @ 2011-12-01 23:32 UTC (permalink / raw) To: Sebastian Spaeth, Justus Winter, notmuch On Thu, 01 Dec 2011 22:25:41 +0100, Sebastian Spaeth <Sebastian@SSpaeth.de> wrote: > This strikes me as a rather good thing, so the patches went in. Hah, I've just seen this, and I'm going to guess that it fixes my problems too. ... I've tested and it seems to work, so my patch is unneeded witht his one. Thanks, James ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 1/2] python: add classes to wrap all notmuch_*_t types 2011-12-01 23:32 ` James Westby @ 2011-12-02 12:35 ` Justus Winter 2011-12-02 14:20 ` James Westby 0 siblings, 1 reply; 23+ messages in thread From: Justus Winter @ 2011-12-02 12:35 UTC (permalink / raw) To: James Westby, Sebastian Spaeth, notmuch [-- Attachment #1: Type: text/plain, Size: 646 bytes --] Quoting James Westby (2011-12-02 00:32:30) >On Thu, 01 Dec 2011 22:25:41 +0100, Sebastian Spaeth <Sebastian@SSpaeth.de> wrote: >> This strikes me as a rather good thing, so the patches went in. > >Hah, I've just seen this, and I'm going to guess that it fixes my >problems too. > >... > >I've tested and it seems to work, so my patch is unneeded witht his one. Huh, strange. My patch isn't supposed to change anything, it just enables the ctypes package to check whether the functions from libnotmuch are called with the right parameters, thus preventing mistakes when changing the python bindings in the future. Cheers, Justus [-- Attachment #2: .signature --] [-- Type: application/octet-stream, Size: 17 bytes --] love u alot @,@ ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 1/2] python: add classes to wrap all notmuch_*_t types 2011-12-02 12:35 ` Justus Winter @ 2011-12-02 14:20 ` James Westby 2011-12-02 23:24 ` James Westby 0 siblings, 1 reply; 23+ messages in thread From: James Westby @ 2011-12-02 14:20 UTC (permalink / raw) To: Justus Winter, Sebastian Spaeth, notmuch On Fri, 02 Dec 2011 13:35:11 +0100, Justus Winter <4winter@informatik.uni-hamburg.de> wrote: > Huh, strange. My patch isn't supposed to change anything, it just > enables the ctypes package to check whether the functions from > libnotmuch are called with the right parameters, thus preventing > mistakes when changing the python bindings in the future. Where .restype is set to c_void_p ctypes spots this and returns it as int32. Where it's set to another callable (e.g. your custom types) it actually wraps the value by passing it to the callable and returning the result. Then, because your custom types are pointers, it stores them in an appropriate value, and also stops the storage being reused. I'll test again to make sure that I have this correct, but my tests yesterday certainly suggested that your patches fixed this. Thanks, James ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 1/2] python: add classes to wrap all notmuch_*_t types 2011-12-02 14:20 ` James Westby @ 2011-12-02 23:24 ` James Westby 2011-12-03 2:11 ` Justus Winter 0 siblings, 1 reply; 23+ messages in thread From: James Westby @ 2011-12-02 23:24 UTC (permalink / raw) To: Justus Winter, Sebastian Spaeth, notmuch On Fri, 02 Dec 2011 09:20:35 -0500, James Westby <jw+debian@jameswestby.net> wrote: > I'll test again to make sure that I have this correct, but my tests > yesterday certainly suggested that your patches fixed this. Yep, segfaults a plenty dropping your second patch that go away again when it is applied once more. Thanks, James ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 1/2] python: add classes to wrap all notmuch_*_t types 2011-12-02 23:24 ` James Westby @ 2011-12-03 2:11 ` Justus Winter 0 siblings, 0 replies; 23+ messages in thread From: Justus Winter @ 2011-12-03 2:11 UTC (permalink / raw) To: James Westby, Sebastian Spaeth, notmuch [-- Attachment #1: Type: text/plain, Size: 406 bytes --] Quoting James Westby (2011-12-03 00:24:18) >On Fri, 02 Dec 2011 09:20:35 -0500, James Westby <jw+debian@jameswestby.net> wrote: >> I'll test again to make sure that I have this correct, but my tests >> yesterday certainly suggested that your patches fixed this. > >Yep, segfaults a plenty dropping your second patch that go away again >when it is applied once more. Happy to hear that :) Justus [-- Attachment #2: .signature --] [-- Type: application/octet-stream, Size: 17 bytes --] love u alot @,@ ^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2014-01-26 14:03 UTC | newest] Thread overview: 23+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-10-09 22:12 [PATCH 1/2] python: add classes to wrap all notmuch_*_t types Justus Winter 2011-10-09 22:12 ` [PATCH 2/2] python: annotate all calls into libnotmuch with types Justus Winter 2011-12-06 10:46 ` Patrick Totzke 2011-12-06 11:12 ` Sebastian Spaeth 2011-12-06 11:44 ` Patrick Totzke 2011-12-06 12:05 ` Sebastian Spaeth [not found] ` <notmuch-sha1-f155d93e11888b35377531dd556b03fd493b7590> 2011-12-07 18:49 ` Justus Winter [not found] ` <notmuch-sha1-c3821ec5e6ef2f83665b03ba10fdfff871f70c2b> 2011-12-07 19:05 ` Justus Winter 2014-01-24 13:17 ` David Bremner 2014-01-24 16:33 ` Justus Winter 2014-01-25 1:40 ` David Bremner 2014-01-25 3:07 ` [PATCH] lib: update documentation for notmuch_database_get_directory David Bremner 2014-01-25 11:46 ` Tomi Ollila 2014-01-26 14:02 ` David Bremner 2014-01-24 13:25 ` [PATCH 2/2] python: annotate all calls into libnotmuch with types David Bremner 2011-11-02 7:25 ` [PATCH 1/2] python: add classes to wrap all notmuch_*_t types Sebastian Spaeth 2011-11-28 12:36 ` Justus Winter 2011-12-01 21:25 ` Sebastian Spaeth 2011-12-01 23:32 ` James Westby 2011-12-02 12:35 ` Justus Winter 2011-12-02 14:20 ` James Westby 2011-12-02 23:24 ` James Westby 2011-12-03 2:11 ` Justus Winter
Code repositories for project(s) associated with this public inbox https://yhetil.org/notmuch.git/ This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).