aboutsummaryrefslogtreecommitdiff
path: root/bindings/python-cffi/notmuch2
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2025-08-28 11:00:59 +0200
committerDavid Bremner <david@tethera.net>2025-09-14 13:32:45 -0300
commitc55953e9de408674d71db78ea4fff941972b2f0a (patch)
tree3c343b3d0644d51b596e2cbf16fe586d86d57dae /bindings/python-cffi/notmuch2
parentabdff73a3333b295a599135ad2777e852189e188 (diff)
bindings/python-cffi: handle NOTMUCH_STATUS_OPERATION_INVALIDATED
Raise it as a newly added OperationInvalidatedError exception.
Diffstat (limited to 'bindings/python-cffi/notmuch2')
-rw-r--r--bindings/python-cffi/notmuch2/_base.py28
-rw-r--r--bindings/python-cffi/notmuch2/_build.py6
-rw-r--r--bindings/python-cffi/notmuch2/_errors.py3
-rw-r--r--bindings/python-cffi/notmuch2/_message.py3
-rw-r--r--bindings/python-cffi/notmuch2/_thread.py3
5 files changed, 38 insertions, 5 deletions
diff --git a/bindings/python-cffi/notmuch2/_base.py b/bindings/python-cffi/notmuch2/_base.py
index 1b0b5b7e..1748c372 100644
--- a/bindings/python-cffi/notmuch2/_base.py
+++ b/bindings/python-cffi/notmuch2/_base.py
@@ -176,17 +176,25 @@ class NotmuchIter(NotmuchObject, collections.abc.Iterator):
:type iter_p: cffi.cdata
:param fn_destroy: The CFFI notmuch_*_destroy function.
:param fn_valid: The CFFI notmuch_*_valid function.
+ :param fn_status: The CFFI notmuch_*_status function. Exactly one of
+ fn_valid or fn_status must be provided, the other one must be None.
:param fn_get: The CFFI notmuch_*_get function.
:param fn_next: The CFFI notmuch_*_move_to_next function.
"""
_iter_p = MemoryPointer()
def __init__(self, parent, iter_p,
- *, fn_destroy, fn_valid, fn_get, fn_next):
+ *, fn_destroy, fn_valid, fn_get, fn_next,
+ fn_status = None):
+ # exactly one of those must be provided
+ assert((fn_valid and not fn_status) or
+ (fn_status and not fn_valid))
+
self._parent = parent
self._iter_p = iter_p
self._fn_destroy = fn_destroy
self._fn_valid = fn_valid
+ self._fn_status = fn_status
self._fn_get = fn_get
self._fn_next = fn_next
@@ -212,6 +220,18 @@ class NotmuchIter(NotmuchObject, collections.abc.Iterator):
pass
self._iter_p = None
+ def _check_status(self):
+ if self._fn_valid:
+ # fall back on fn_valid for iterators that do not implement fn_status
+ if not self._fn_valid(self._iter_p):
+ raise StopIteration
+ else:
+ status = self._fn_status(self._iter_p)
+ if status == capi.lib.NOTMUCH_STATUS_ITERATOR_EXHAUSTED:
+ raise StopIteration
+ elif status != capi.lib.NOTMUCH_STATUS_SUCCESS:
+ raise errors.NotmuchError(status)
+
def __iter__(self):
"""Return the iterator itself.
@@ -222,9 +242,11 @@ class NotmuchIter(NotmuchObject, collections.abc.Iterator):
return self
def __next__(self):
- if not self._fn_valid(self._iter_p):
- raise StopIteration()
+ self._check_status()
obj_p = self._fn_get(self._iter_p)
+ if obj_p == capi.ffi.NULL:
+ self._check_status()
+ raise StopIteration
self._fn_next(self._iter_p)
return obj_p
diff --git a/bindings/python-cffi/notmuch2/_build.py b/bindings/python-cffi/notmuch2/_build.py
index 0429691a..2f3152c6 100644
--- a/bindings/python-cffi/notmuch2/_build.py
+++ b/bindings/python-cffi/notmuch2/_build.py
@@ -56,6 +56,8 @@ ffibuilder.cdef(
NOTMUCH_STATUS_BAD_QUERY_SYNTAX,
NOTMUCH_STATUS_NO_MAIL_ROOT,
NOTMUCH_STATUS_CLOSED_DATABASE,
+ NOTMUCH_STATUS_ITERATOR_EXHAUSTED,
+ NOTMUCH_STATUS_OPERATION_INVALIDATED,
NOTMUCH_STATUS_LAST_STATUS
} notmuch_status_t;
typedef enum {
@@ -187,6 +189,8 @@ ffibuilder.cdef(
notmuch_bool_t
notmuch_threads_valid (notmuch_threads_t *threads);
+ notmuch_status_t
+ notmuch_threads_status (notmuch_threads_t *threads);
notmuch_thread_t *
notmuch_threads_get (notmuch_threads_t *threads);
void
@@ -221,6 +225,8 @@ ffibuilder.cdef(
notmuch_bool_t
notmuch_messages_valid (notmuch_messages_t *messages);
+ notmuch_status_t
+ notmuch_messages_status (notmuch_messages_t *messages);
notmuch_message_t *
notmuch_messages_get (notmuch_messages_t *messages);
void
diff --git a/bindings/python-cffi/notmuch2/_errors.py b/bindings/python-cffi/notmuch2/_errors.py
index 17c3ad9c..483e794b 100644
--- a/bindings/python-cffi/notmuch2/_errors.py
+++ b/bindings/python-cffi/notmuch2/_errors.py
@@ -28,6 +28,8 @@ class NotmuchError(Exception):
ReadOnlyDatabaseError,
capi.lib.NOTMUCH_STATUS_XAPIAN_EXCEPTION:
XapianError,
+ capi.lib.NOTMUCH_STATUS_OPERATION_INVALIDATED:
+ OperationInvalidatedError,
capi.lib.NOTMUCH_STATUS_FILE_ERROR:
FileError,
capi.lib.NOTMUCH_STATUS_FILE_NOT_EMAIL:
@@ -92,6 +94,7 @@ class NotmuchError(Exception):
class OutOfMemoryError(NotmuchError): pass
class ReadOnlyDatabaseError(NotmuchError): pass
class XapianError(NotmuchError): pass
+class OperationInvalidatedError(XapianError): pass
class FileError(NotmuchError): pass
class FileNotEmailError(NotmuchError): pass
class DuplicateMessageIdError(NotmuchError): pass
diff --git a/bindings/python-cffi/notmuch2/_message.py b/bindings/python-cffi/notmuch2/_message.py
index 79485238..e31e0c3c 100644
--- a/bindings/python-cffi/notmuch2/_message.py
+++ b/bindings/python-cffi/notmuch2/_message.py
@@ -707,7 +707,8 @@ class MessageIter(base.NotmuchIter):
self._msg_cls = msg_cls
super().__init__(parent, msgs_p,
fn_destroy=capi.lib.notmuch_messages_destroy,
- fn_valid=capi.lib.notmuch_messages_valid,
+ fn_valid=None,
+ fn_status=capi.lib.notmuch_messages_status,
fn_get=capi.lib.notmuch_messages_get,
fn_next=capi.lib.notmuch_messages_move_to_next)
diff --git a/bindings/python-cffi/notmuch2/_thread.py b/bindings/python-cffi/notmuch2/_thread.py
index e883f308..af49d2bf 100644
--- a/bindings/python-cffi/notmuch2/_thread.py
+++ b/bindings/python-cffi/notmuch2/_thread.py
@@ -185,7 +185,8 @@ class ThreadIter(base.NotmuchIter):
self._db = db
super().__init__(parent, threads_p,
fn_destroy=capi.lib.notmuch_threads_destroy,
- fn_valid=capi.lib.notmuch_threads_valid,
+ fn_valid=None,
+ fn_status=capi.lib.notmuch_threads_status,
fn_get=capi.lib.notmuch_threads_get,
fn_next=capi.lib.notmuch_threads_move_to_next)