aboutsummaryrefslogtreecommitdiff
path: root/bindings/python/notmuch/database.py
diff options
context:
space:
mode:
authorJustus Winter <4winter@informatik.uni-hamburg.de>2011-10-10 00:12:54 +0200
committerSebastian Spaeth <Sebastian@SSpaeth.de>2011-12-01 22:24:19 +0100
commit3434d194026ff65217d9342ffe511f67fd71e79f (patch)
treeadcd4621f97ac5143efd378530d62a78f3b937f5 /bindings/python/notmuch/database.py
parente92b438f46a3ad7103299b1c62747f36d9de06bf (diff)
python: annotate all calls into libnotmuch with types
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>
Diffstat (limited to 'bindings/python/notmuch/database.py')
-rw-r--r--bindings/python/notmuch/database.py127
1 files changed, 97 insertions, 30 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)