Hi Jorge, On Fri 20 Nov 2020 at 12:54 -0300, Jorge P. de Morais Neto wrote: > Hi. I am trying to migrate my Python3 script to the new Python bindings > (notmuch2 module). However, I cannot obtain a count of messages > matching a query excluding messages that have an exclude tag. From the > command line: > $ notmuch count 'is:.bf_spam' > 0 > > The CLI command correctly counts zero messages having '.bf_spam' tag, > because all such messages also have the excluded 'spam' tag. But from > Python: > > $ python3 > Python 3.7.3 (default, Jul 25 2020, 13:03:44) > [GCC 8.3.0] on linux > Type "help", "copyright", "credits" or "license" for more information. >>>> import notmuch2 >>>> nm_db=notmuch2.Database() >>>> nm_db.count_messages('is:.bf_spam', exclude_tags=('spam',)) > 379 >>>> nm_db.count_messages('is:.bf_spam', exclude_tags=('spam',), omit_excluded=nm_db.EXCLUDE.FALSE) > 379 >>>> nm_db.count_messages('is:.bf_spam', exclude_tags=('spam',), omit_excluded=nm_db.EXCLUDE.TRUE) > 379 >>>> nm_db.count_messages('is:.bf_spam', exclude_tags=('spam',), omit_excluded=nm_db.EXCLUDE.ALL) > 379 >>>> nm_db.count_messages('is:.bf_spam', exclude_tags=('spam',), omit_excluded=nm_db.EXCLUDE.FLAG) > 379 Personally I find the description of these flags in notmuch.h not very clear and don't claim to understand them (this probably explains the really bad docstring, we should improve those). But I expected to at least see the EXCLUDE.TRUE one, the default, to work. Looking at the implementation I don't seem much that could have gone wrong. However I did notice the bindings fail to check the return code in one call where it probably should, you could try with this patch? diff --git a/bindings/python-cffi/notmuch2/_database.py b/bindings/python-cffi/notmuch2/_database.py index 5ab0f20a..5dbfe68e 100644 --- a/bindings/python-cffi/notmuch2/_database.py +++ b/bindings/python-cffi/notmuch2/_database.py @@ -579,7 +579,10 @@ class Database(base.NotmuchObject): for tag in exclude_tags: if isinstance(tag, str): tag = str.encode('utf-8') - capi.lib.notmuch_query_add_tag_exclude(query_p, tag) + ret = capi.lib.notmuch_query_add_tag_exclude(query_p, tag) + if ret not in [capi.lib.NOTMUCH_STATUS_SUCCESS, + capi.lib.NOTMUCH_STATUS_IGNORED]: + raise errors.NotmuchError(ret) return querymod.Query(self, query_p) def messages(self, query, *, To experiment you could also raise the exception for NOTMUCH_STATUS_IGNORED, even though for the bindings to silently swallow this is probably the best (this is really the bindings being more limiting than the C lib, if this bothers ppl we could add another keyword arg to let this raise as well). While the above patch is probably good, I feel like it's clutching at straws and unlikely to solve your problem. Could you try to reproduce this in plain C or maybe even in pretend-plain-c by using the capi.lib.notmuch_* calls directly? Cheers, Floris _______________________________________________ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-leave@notmuchmail.org