Update on python-cffi bindings

Floris Bruynooghe flub at devork.be
Sun Dec 17 10:08:18 PST 2017


Hi all,

Thanks for all the feedback on an early post of my CFFI-based libnotmuch
Python bindings.  I've now completed these somewhat more and they now
have most of the functionality.  Here's what's new since last time:

- All tests pass on Python 3.5, 3.6 and pypy3.5

  I could probably add 3.4 as well, but I got the impression from people
  this was less important.  Likewise it seemed there was a more-or-less
  consensus that missing python 2.7 is no big deal.

- properties supported as a mapping

  This behaves as a normal mapping, with one extra method:
  getall(prefix='', *, exact=False).  Which returns an iterator rather
  then just one item.

- queries and threads

  There's now a Database.messages(query, *,
                                  omit_excluded=EXCLUDE.TRUE,
                                  sort=SORT.UNSORTED,
                                  exclude=tags=None)
  function.  It behaves as a generator, i.e. an iterator is returned.
  Likewise for Database.threads().  Also Database.count_messages() and
  Database.count_threads() all have the same signature (well, they
  return ints).

- Message.frozen() as a context manager

  with msg.frozen():
      msg.clear()
      raise Exception('oops')

  just works, that's less obvious to make this work then it looks but
  seemed worth it to look native in Python.

I've pushed all changes to github.com/flub/notmuch on the cffi branch.
I'd be keen to hear more feedback from other people.

Things still to do:

- Nice docs, there's comprehensive docstrings now but sphinx docs are
  clearly superior.

- A few API bits, e.g. Database.upgrade() and some others.  They're
  probably less important and I'll likely only do them as people request
  them.

- Improve finalization.  It'd be nice to give users direct access to
  .destroy() methods to free the memory, or even turn everything into
  (optional) context managers which would automatically call .destroy():

  with db.threads('tag:foo') as threads:
      for thread in threads:
          pass

  This is probably nice for long-running applications which may want to
  be somewhat careful about their memory.  But finalizers need to be
  implemented with a slightly more extended version of
  weakref.finalizer() for this to be safe.

Let me know what you think.  I'd also be happy to re-post a patch, but
it's huge and also the commits not very clean currently.  Please let me
know the best way to proceed.

Floris


More information about the notmuch mailing list