unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* [PATCH 1/2] python: add bindings for notmuch_database_get_config{, _list}
@ 2017-06-04 17:20 l-m-h
  2017-06-04 17:20 ` [PATCH 2/2] python: add convenience function to get named queries l-m-h
  2017-06-10 11:10 ` [PATCH 1/2] python: add bindings for notmuch_database_get_config{, _list} David Bremner
  0 siblings, 2 replies; 18+ messages in thread
From: l-m-h @ 2017-06-04 17:20 UTC (permalink / raw)
  To: notmuch; +Cc: Lucas Hoffmann

[-- Attachment #1: Type: text/plain, Size: 44 bytes --]

This is a multi-part message in MIME format.

[-- Attachment #2: Type: text/plain, Size: 220 bytes --]

---
 bindings/python/docs/source/database.rst |  4 ++
 bindings/python/notmuch/database.py      | 85 ++++++++++++++++++++++++++++++++
 bindings/python/notmuch/globals.py       |  5 ++
 3 files changed, 94 insertions(+)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0001-python-add-bindings-for-notmuch_database_get_config-.patch --]
[-- Type: text/x-patch; name="0001-python-add-bindings-for-notmuch_database_get_config-.patch", Size: 5075 bytes --]

diff --git a/bindings/python/docs/source/database.rst b/bindings/python/docs/source/database.rst
index 5f1cdc14..376dfb02 100644
--- a/bindings/python/docs/source/database.rst
+++ b/bindings/python/docs/source/database.rst
@@ -37,6 +37,10 @@
 
    .. automethod:: create_query
 
+   .. automethod:: get_config
+
+   .. automethod:: get_config_list
+
    .. attribute:: Database.MODE
 
      Defines constants that are used as the mode in which to open a database.
diff --git a/bindings/python/notmuch/database.py b/bindings/python/notmuch/database.py
index 8f918069..9d7737b2 100644
--- a/bindings/python/notmuch/database.py
+++ b/bindings/python/notmuch/database.py
@@ -25,6 +25,7 @@ from .globals import (
     nmlib,
     Enum,
     _str,
+    NotmuchConfigListP,
     NotmuchDatabaseP,
     NotmuchDirectoryP,
     NotmuchMessageP,
@@ -624,3 +625,87 @@ class Database(object):
             raise NotmuchError(message="No DB path specified"
                                        " and no user default found")
         return config.get('database', 'path')
+
+    """notmuch_database_get_config"""
+    _get_config = nmlib.notmuch_database_get_config
+    _get_config.argtypes = [NotmuchDatabaseP, c_char_p, POINTER(c_char_p)]
+    _get_config.restype = c_uint
+
+    def get_config(self, key):
+        """Return the value of the given config key.
+
+        Note that only config values that are stored in the database are
+        searched and returned.  The config file is not read.
+
+        :param key: the config key under which a value should be looked up, it
+                    should probably be in the form "section.key"
+        :type key:  str
+        :returns:   the config value or the empty string if no value is present
+                    for that key
+        :rtype:     str
+        :raises:    :exc:`NotmuchError` or derived exception in case of
+                    failure.
+
+        """
+        self._assert_db_is_initialized()
+        return_string = c_char_p()
+        status = self._get_config(self._db, _str(key), byref(return_string))
+        if status != STATUS.SUCCESS:
+            raise NotmuchError(status)
+        return return_string.value.decode('utf-8')
+
+    """notmuch_database_get_config_list"""
+    _get_config_list = nmlib.notmuch_database_get_config_list
+    _get_config_list.argtypes = [NotmuchDatabaseP, c_char_p,
+                                 POINTER(NotmuchConfigListP)]
+    _get_config_list.restype = c_uint
+
+    _config_list_valid = nmlib.notmuch_config_list_valid
+    _config_list_valid.argtypes = [NotmuchConfigListP]
+    _config_list_valid.restype = bool
+
+    _config_list_key = nmlib.notmuch_config_list_key
+    _config_list_key.argtypes = [NotmuchConfigListP]
+    _config_list_key.restype = c_char_p
+
+    _config_list_value = nmlib.notmuch_config_list_value
+    _config_list_value.argtypes = [NotmuchConfigListP]
+    _config_list_value.restype = c_char_p
+
+    _config_list_move_to_next = nmlib.notmuch_config_list_move_to_next
+    _config_list_move_to_next.argtypes = [NotmuchConfigListP]
+    _config_list_move_to_next.restype = None
+
+    _config_list_destroy = nmlib.notmuch_config_list_destroy
+    _config_list_destroy.argtypes = [NotmuchConfigListP]
+    _config_list_destroy.restype = None
+
+    def get_config_list(self, prefix):
+        """Return a list of key, value pairs where the start of key matches the
+        given prefix
+
+        Note that only config values that are stored in the database are
+        searched and returned.  The config file is not read.
+
+        :param prefix: a string by which the keys should be selected
+        :type prefix:  str
+        :returns:      all key-value pairs where `prefix` matches the beginning
+                       of the key
+        :rtype:        a list of pairs of str
+        :raises:      :exc:`NotmuchError` or derived exception in case of
+                      failure.
+
+        """
+        self._assert_db_is_initialized()
+        config_list_p = NotmuchConfigListP()
+        status = self._get_config_list(self._db, _str(prefix),
+                                       byref(config_list_p))
+        if status != STATUS.SUCCESS:
+            raise NotmuchError(status)
+        config_list = []
+        while self._config_list_valid(config_list_p):
+            key = self._config_list_key(config_list_p).decode('utf-8')
+            value = self._config_list_value(config_list_p).decode('utf-8')
+            config_list.append((key, value))
+            self._config_list_move_to_next(config_list_p)
+        return config_list
diff --git a/bindings/python/notmuch/globals.py b/bindings/python/notmuch/globals.py
index b1eec2cf..b33e10d3 100644
--- a/bindings/python/notmuch/globals.py
+++ b/bindings/python/notmuch/globals.py
@@ -88,3 +88,8 @@ NotmuchDirectoryP = POINTER(NotmuchDirectoryS)
 class NotmuchFilenamesS(Structure):
     pass
 NotmuchFilenamesP = POINTER(NotmuchFilenamesS)
+
+
+class NotmuchConfigListS(Structure):
+    pass
+NotmuchConfigListP = POINTER(NotmuchConfigListS)

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 2/2] python: add convenience function to get named queries
  2017-06-04 17:20 [PATCH 1/2] python: add bindings for notmuch_database_get_config{, _list} l-m-h
@ 2017-06-04 17:20 ` l-m-h
  2017-06-10 11:37   ` David Bremner
  2017-06-10 11:10 ` [PATCH 1/2] python: add bindings for notmuch_database_get_config{, _list} David Bremner
  1 sibling, 1 reply; 18+ messages in thread
From: l-m-h @ 2017-06-04 17:20 UTC (permalink / raw)
  To: notmuch; +Cc: Lucas Hoffmann

[-- Attachment #1: Type: text/plain, Size: 44 bytes --]

This is a multi-part message in MIME format.

[-- Attachment #2: Type: text/plain, Size: 87 bytes --]

---
 bindings/python/notmuch/database.py | 7 +++++++
 1 file changed, 7 insertions(+)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-python-add-convenience-function-to-get-named-queries.patch --]
[-- Type: text/x-patch; name="0002-python-add-convenience-function-to-get-named-queries.patch", Size: 664 bytes --]

diff --git a/bindings/python/notmuch/database.py b/bindings/python/notmuch/database.py
index 9d7737b2..1fd312dd 100644
--- a/bindings/python/notmuch/database.py
+++ b/bindings/python/notmuch/database.py
@@ -709,3 +709,10 @@ class Database(object):
             config_list.append((key, value))
             self._config_list_move_to_next(config_list_p)
         return config_list
+
+    def get_all_named_queries(self):
+        """Returns a dict of all named queries mapped to their search queries.
+
+        This function is a python extension and not in the underlying C API.
+        """
+        return {k[6:]: v for k, v in self.get_config_list('query.')}

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/2] python: add bindings for notmuch_database_get_config{, _list}
  2017-06-04 17:20 [PATCH 1/2] python: add bindings for notmuch_database_get_config{, _list} l-m-h
  2017-06-04 17:20 ` [PATCH 2/2] python: add convenience function to get named queries l-m-h
@ 2017-06-10 11:10 ` David Bremner
  2017-06-20 20:06   ` Lucas Hoffmann
  1 sibling, 1 reply; 18+ messages in thread
From: David Bremner @ 2017-06-10 11:10 UTC (permalink / raw)
  To: l-m-h, notmuch; +Cc: Lucas Hoffmann

l-m-h@web.de writes:


Thanks for writing these bindings, it will be good to have the bindings
(almost) catch up to the library again.


We generally expect more than just a subject line in the commit message

   https://notmuchmail.org/contributing/#index5h2

> +    def get_config(self, key):
> +        """Return the value of the given config key.

I guess we will eventually want set_config as well, even if it's not
needed for your immediate application. It might save future confusion to
add them both at the same time (unless there's something complicated
about adding set_config).

It would be good to add a couple tests. test/T590-libconfig.sh has some
C tests. I think the first one, labelled
"notmuch_database_{set,get}_config" could just be translated into python
(maybe even replace the C test with the python one, depending what
others think).

> +    def get_config_list(self, prefix):

I don't object to the simplified interface, but I would like to know
what we can do if it becomes a performance bottleneck.  Would it be
possible to replace building the list with a generator (yield statement)
without changing client code? or should we take the leap now?

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 2/2] python: add convenience function to get named queries
  2017-06-04 17:20 ` [PATCH 2/2] python: add convenience function to get named queries l-m-h
@ 2017-06-10 11:37   ` David Bremner
  0 siblings, 0 replies; 18+ messages in thread
From: David Bremner @ 2017-06-10 11:37 UTC (permalink / raw)
  To: l-m-h, notmuch; +Cc: Lucas Hoffmann

l-m-h@web.de writes:

see above re: commit messages.

> ---
>  bindings/python/notmuch/database.py | 7 +++++++
>  1 file changed, 7 insertions(+)
>
> +
> +    def get_all_named_queries(self):
> +        """Returns a dict of all named queries mapped to their search queries.
> +
> +        This function is a python extension and not in the underlying C API.
> +        """
> +        return {k[6:]: v for k, v in self.get_config_list('query.')}

I have somewhat mixed feelings about this. I don't really like the
python bindings diverging from the C library.  It's also not clear it's
worth supporting a new API entry (since e.g. if this goes in it also
needs a test) to save the python client one line of code. On the
positive side I can see there is arguably a missing abstraction on the
library side, as those particular config items are special.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/2] python: add bindings for notmuch_database_get_config{, _list}
  2017-06-10 11:10 ` [PATCH 1/2] python: add bindings for notmuch_database_get_config{, _list} David Bremner
@ 2017-06-20 20:06   ` Lucas Hoffmann
  2017-06-26 23:19     ` David Bremner
  0 siblings, 1 reply; 18+ messages in thread
From: Lucas Hoffmann @ 2017-06-20 20:06 UTC (permalink / raw)
  To: l-m-h, notmuch

[-- Attachment #1: Type: text/plain, Size: 3273 bytes --]

Now I finally found some time to come back to this.

Quoting David Bremner (2017-06-10 13:10:13)
> Thanks for writing these bindings, it will be good to have the bindings
> (almost) catch up to the library again.

My pleasure.

> We generally expect more than just a subject line in the commit message

OK.

> I guess we will eventually want set_config as well, even if it's not
> needed for your immediate application. It might save future confusion to
> add them both at the same time (unless there's something complicated
> about adding set_config).

Done, will send it out the next time I send the patches.

> It would be good to add a couple tests. test/T590-libconfig.sh has some
> C tests. I think the first one, labelled
> "notmuch_database_{set,get}_config" could just be translated into python
> (maybe even replace the C test with the python one, depending what
> others think).

Started it, will also come with the next round.  I would not remove the
C tests.  It could always happen that something is broken with the
python bindings even though the C bindings are fine.

> > +    def get_config_list(self, prefix):
>
> I don't object to the simplified interface, but I would like to know
> what we can do if it becomes a performance bottleneck.  Would it be
> possible to replace building the list with a generator (yield statement)
> without changing client code? or should we take the leap now?

I don't see a reason to have python programmers handle "manual
iterators" or however you want to call the thing the C code does there.
So I would like to keep *some* simplified interface as well.

It is very easy to turn this into a generator.  But then I consider the
name a mismatch.  If it is called "get_config_list" it should return a
list.  I could add get_config_iterator or get_config_generator and turn
get_config_list into a wrapper:

def get_config_list(self, prefix):
    return list(self.get_config_iterator(prefix))

The only problem one could see with this additional entry point is what
you said in id:87wp8kcbvg.fsf@tethera.net about the function
get_all_named_queries (quote below), namely that the names of the python
bindings diverge from the names of the C bindings.  I don't think that
there will be a performance problem as I assume that there will not be
many config values in the database so storing them in memory should not
be a problem.

Quoting David Bremner (Message-ID: <87wp8kcbvg.fsf@tethera.net>)
> I have somewhat mixed feelings about this. I don't really like the
> python bindings diverging from the C library.  It's also not clear it's
> worth supporting a new API entry (since e.g. if this goes in it also
> needs a test) to save the python client one line of code. On the
> positive side I can see there is arguably a missing abstraction on the
> library side, as those particular config items are special.

I think I will drop this commit
(34d9febc53775a24ca9e1bb1abcef64ea9196b12).

If we want to introduce some more abstract interface in python we could
also do this:

def get_configs(self, prefix):
    return dict(self.get_config_iterator(prefix))

(or with a different name like get_config_dict)

Which interface would you prefer?

Lucas

[-- Attachment #2: signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

-----BEGIN PGP SIGNATURE-----

iQEzBAABCAAdFiEE96z4mcwnF18GSMtNYLcfxwAaQaEFAllJgEIACgkQYLcfxwAa
QaHRYQgApqtnjjTvA2hcu3xfvd+tKGTXv8KDn8yCfWcgrnM92cBJv9oUg0vM8q62
ZC4yZfaw3WzlxubpCLM9goE6rr3yqLs99mHUxPb1bj8P+xoJXSSKfR07uT54zvhZ
vmSTV884duRNo8pVeb5JQuwXEDROqP/R3jAkbBz9OGtjggQZJuMQwfXBPj8I7F8s
rPCebTsdUs41ksYUSuVzBwh2qjL77IRAWZplhKYOXJJxyLjTNoLcYUZ7c/9H3Xkv
EA3cGEv8r8uhw/FxkwuH4Qa4SDLQ22MHtTvlCSQZ4+ecDKkoXuWCyYnZoWPy7Ol/
EgFc8VKpN+plv0Vrt265tjTbNrZ3gQ==
=D00Y
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/2] python: add bindings for notmuch_database_get_config{, _list}
  2017-06-20 20:06   ` Lucas Hoffmann
@ 2017-06-26 23:19     ` David Bremner
  2017-12-07 11:40       ` [PATCH 0/6] " l-m-h
                         ` (6 more replies)
  0 siblings, 7 replies; 18+ messages in thread
From: David Bremner @ 2017-06-26 23:19 UTC (permalink / raw)
  To: Lucas Hoffmann, notmuch

Lucas Hoffmann <l-m-h@web.de> writes:

>
> I don't see a reason to have python programmers handle "manual
> iterators" or however you want to call the thing the C code does there.
> So I would like to keep *some* simplified interface as well.
>
> It is very easy to turn this into a generator.  But then I consider the
> name a mismatch.  If it is called "get_config_list" it should return a
> list.  I could add get_config_iterator or get_config_generator and turn
> get_config_list into a wrapper:

For starters I'd just create get_config_{iterator,generator}, which ever
is a more pythonic name. As you point out below, it's easy to turn that
into a list or a dictionary.
>
> The only problem one could see with this additional entry point is what
> you said in id:87wp8kcbvg.fsf@tethera.net about the function
> get_all_named_queries (quote below), namely that the names of the python
> bindings diverge from the names of the C bindings.

It's not so much the names diverging that I worry about as the
functionality. The C library provides (effectively) a generator, so the
bindings should too.

d

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 0/6] python: add bindings for notmuch_database_get_config{, _list}
  2017-06-26 23:19     ` David Bremner
@ 2017-12-07 11:40       ` l-m-h
  2017-12-19 11:13         ` David Bremner
  2017-12-07 11:40       ` [PATCH 1/6] python: add bindings to access config l-m-h
                         ` (5 subsequent siblings)
  6 siblings, 1 reply; 18+ messages in thread
From: l-m-h @ 2017-12-07 11:40 UTC (permalink / raw)
  To: notmuch; +Cc: Lucas Hoffmann

[-- Attachment #1: Type: text/plain, Size: 44 bytes --]

This is a multi-part message in MIME format.

[-- Attachment #2: Type: text/plain, Size: 1039 bytes --]

Comming back after a long time (sorry for the wait).

I now changed the binding for notmuch_database_get_config_list into a
generator.  It is called get_configs in the python bindings (the "s"
should indicate the iterable/generator nature like for dict.items or
dict.keys).

Tests and the set_config entry point were also added.

If you want you can merge it as is or I can squash the commits in any
way you want.

Lucas Hoffmann (6):
  python: add bindings to access config
  python: add default arg to get_config_list
  python: turn get_config_list into a generator
  test: Add tests for new python bindings
  python: Rename get_config_list to get_configs
  test: Add test to unset config items with the python bindings

 bindings/python/docs/source/database.rst |   6 ++
 bindings/python/notmuch/database.py      | 111 ++++++++++++++++++++++++++++++-
 bindings/python/notmuch/globals.py       |   5 ++
 test/T390-python.sh                      |  81 ++++++++++++++++++++++
 4 files changed, 202 insertions(+), 1 deletion(-)

-- 
2.15.1

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 1/6] python: add bindings to access config
  2017-06-26 23:19     ` David Bremner
  2017-12-07 11:40       ` [PATCH 0/6] " l-m-h
@ 2017-12-07 11:40       ` l-m-h
  2017-12-07 11:40       ` [PATCH 2/6] python: add default arg to get_config_list l-m-h
                         ` (4 subsequent siblings)
  6 siblings, 0 replies; 18+ messages in thread
From: l-m-h @ 2017-12-07 11:40 UTC (permalink / raw)
  To: notmuch; +Cc: Lucas Hoffmann

[-- Attachment #1: Type: text/plain, Size: 44 bytes --]

This is a multi-part message in MIME format.

[-- Attachment #2: Type: text/plain, Size: 590 bytes --]


The C functions notmuch_database_get_config,
notmuch_database_get_config_list and notmuch_database_set_config are
part of the official C bindings.  So there should also be some python
bindings for them.

Also they are the only way to access the named queries introduced in
b9bf3f44.

The interface of the python functions is designed to be close to the C
functions.
---
 bindings/python/docs/source/database.rst |   6 ++
 bindings/python/notmuch/database.py      | 106 +++++++++++++++++++++++++++++++
 bindings/python/notmuch/globals.py       |   5 ++
 3 files changed, 117 insertions(+)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0001-python-add-bindings-to-access-config.patch --]
[-- Type: text/x-patch; name="0001-python-add-bindings-to-access-config.patch", Size: 5831 bytes --]

diff --git a/bindings/python/docs/source/database.rst b/bindings/python/docs/source/database.rst
index 079dc754..f9567949 100644
--- a/bindings/python/docs/source/database.rst
+++ b/bindings/python/docs/source/database.rst
@@ -37,6 +37,12 @@
 
    .. automethod:: create_query
 
+   .. automethod:: get_config
+
+   .. automethod:: get_config_list
+
+   .. automethod:: set_config
+
    .. attribute:: Database.MODE
 
      Defines constants that are used as the mode in which to open a database.
diff --git a/bindings/python/notmuch/database.py b/bindings/python/notmuch/database.py
index 1279804a..2866b860 100644
--- a/bindings/python/notmuch/database.py
+++ b/bindings/python/notmuch/database.py
@@ -26,6 +26,7 @@ from .globals import (
     nmlib,
     Enum,
     _str,
+    NotmuchConfigListP,
     NotmuchDatabaseP,
     NotmuchDirectoryP,
     NotmuchMessageP,
@@ -634,3 +635,108 @@ class Database(object):
             raise NotmuchError(message="No DB path specified"
                                        " and no user default found")
         return config.get('database', 'path')
+
+    """notmuch_database_get_config"""
+    _get_config = nmlib.notmuch_database_get_config
+    _get_config.argtypes = [NotmuchDatabaseP, c_char_p, POINTER(c_char_p)]
+    _get_config.restype = c_uint
+
+    def get_config(self, key):
+        """Return the value of the given config key.
+
+        Note that only config values that are stored in the database are
+        searched and returned.  The config file is not read.
+
+        :param key: the config key under which a value should be looked up, it
+                    should probably be in the form "section.key"
+        :type key:  str
+        :returns:   the config value or the empty string if no value is present
+                    for that key
+        :rtype:     str
+        :raises:    :exc:`NotmuchError` in case of failure.
+
+        """
+        self._assert_db_is_initialized()
+        return_string = c_char_p()
+        status = self._get_config(self._db, _str(key), byref(return_string))
+        if status != STATUS.SUCCESS:
+            raise NotmuchError(status)
+        return return_string.value.decode('utf-8')
+
+    """notmuch_database_get_config_list"""
+    _get_config_list = nmlib.notmuch_database_get_config_list
+    _get_config_list.argtypes = [NotmuchDatabaseP, c_char_p,
+                                 POINTER(NotmuchConfigListP)]
+    _get_config_list.restype = c_uint
+
+    _config_list_valid = nmlib.notmuch_config_list_valid
+    _config_list_valid.argtypes = [NotmuchConfigListP]
+    _config_list_valid.restype = bool
+
+    _config_list_key = nmlib.notmuch_config_list_key
+    _config_list_key.argtypes = [NotmuchConfigListP]
+    _config_list_key.restype = c_char_p
+
+    _config_list_value = nmlib.notmuch_config_list_value
+    _config_list_value.argtypes = [NotmuchConfigListP]
+    _config_list_value.restype = c_char_p
+
+    _config_list_move_to_next = nmlib.notmuch_config_list_move_to_next
+    _config_list_move_to_next.argtypes = [NotmuchConfigListP]
+    _config_list_move_to_next.restype = None
+
+    _config_list_destroy = nmlib.notmuch_config_list_destroy
+    _config_list_destroy.argtypes = [NotmuchConfigListP]
+    _config_list_destroy.restype = None
+
+    def get_config_list(self, prefix):
+        """Return a list of key, value pairs where the start of key matches the
+        given prefix
+
+        Note that only config values that are stored in the database are
+        searched and returned.  The config file is not read.
+
+        :param prefix: a string by which the keys should be selected
+        :type prefix:  str
+        :returns:      all key-value pairs where `prefix` matches the beginning
+                       of the key
+        :rtype:        a list of pairs of str
+        :raises:      :exc:`NotmuchError` in case of failure.
+
+        """
+        self._assert_db_is_initialized()
+        config_list_p = NotmuchConfigListP()
+        status = self._get_config_list(self._db, _str(prefix),
+                                       byref(config_list_p))
+        if status != STATUS.SUCCESS:
+            raise NotmuchError(status)
+        config_list = []
+        while self._config_list_valid(config_list_p):
+            key = self._config_list_key(config_list_p).decode('utf-8')
+            value = self._config_list_value(config_list_p).decode('utf-8')
+            config_list.append((key, value))
+            self._config_list_move_to_next(config_list_p)
+        return config_list
+
+    """notmuch_database_set_config"""
+    _set_config = nmlib.notmuch_database_set_config
+    _set_config.argtypes = [NotmuchDatabaseP, c_char_p, c_char_p]
+    _set_config.restype = c_uint
+
+    def set_config(self, key, value):
+        """Set a config value in the notmuch database.
+
+        If an empty string is provided as `value` the `key` is unset!
+
+        :param key:   the key to set
+        :type key:    str
+        :param value: the value to store under `key`
+        :type value:  str
+        :returns:     None
+        :raises:      :exc:`NotmuchError` in case of failure.
+
+        """
+        self._assert_db_is_initialized()
+        status = self._set_config(self._db, _str(key), _str(value))
+        if status != STATUS.SUCCESS:
+            raise NotmuchError(status)
diff --git a/bindings/python/notmuch/globals.py b/bindings/python/notmuch/globals.py
index b1eec2cf..b33e10d3 100644
--- a/bindings/python/notmuch/globals.py
+++ b/bindings/python/notmuch/globals.py
@@ -88,3 +88,8 @@ NotmuchDirectoryP = POINTER(NotmuchDirectoryS)
 class NotmuchFilenamesS(Structure):
     pass
 NotmuchFilenamesP = POINTER(NotmuchFilenamesS)
+
+
+class NotmuchConfigListS(Structure):
+    pass
+NotmuchConfigListP = POINTER(NotmuchConfigListS)

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 2/6] python: add default arg to get_config_list
  2017-06-26 23:19     ` David Bremner
  2017-12-07 11:40       ` [PATCH 0/6] " l-m-h
  2017-12-07 11:40       ` [PATCH 1/6] python: add bindings to access config l-m-h
@ 2017-12-07 11:40       ` l-m-h
  2017-12-07 11:40       ` [PATCH 3/6] python: turn get_config_list into a generator l-m-h
                         ` (3 subsequent siblings)
  6 siblings, 0 replies; 18+ messages in thread
From: l-m-h @ 2017-12-07 11:40 UTC (permalink / raw)
  To: notmuch; +Cc: Lucas Hoffmann

[-- Attachment #1: Type: text/plain, Size: 44 bytes --]

This is a multi-part message in MIME format.

[-- Attachment #2: Type: text/plain, Size: 273 bytes --]


It makes the function a little more intuitive to use and does not
diverge much from the original function signature.

Also an example is added to the docstring.
---
 bindings/python/notmuch/database.py | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-python-add-default-arg-to-get_config_list.patch --]
[-- Type: text/x-patch; name="0002-python-add-default-arg-to-get_config_list.patch", Size: 1522 bytes --]

diff --git a/bindings/python/notmuch/database.py b/bindings/python/notmuch/database.py
index 2866b860..54966307 100644
--- a/bindings/python/notmuch/database.py
+++ b/bindings/python/notmuch/database.py
@@ -313,7 +313,7 @@ class Database(object):
         """
         self._assert_db_is_initialized()
         status = Database._upgrade(self._db, None, None)
-        #TODO: catch exceptions, document return values and etc
+        # TODO: catch exceptions, document return values and etc
         return status
 
     _begin_atomic = nmlib.notmuch_database_begin_atomic
@@ -689,12 +689,19 @@ class Database(object):
     _config_list_destroy.argtypes = [NotmuchConfigListP]
     _config_list_destroy.restype = None
 
-    def get_config_list(self, prefix):
+    def get_config_list(self, prefix=''):
         """Return a list of key, value pairs where the start of key matches the
         given prefix
 
         Note that only config values that are stored in the database are
-        searched and returned.  The config file is not read.
+        searched and returned.  The config file is not read.  If no `prefix` is
+        given all config values are returned.
+
+        This could be used to get all config values or all named queries into a
+        dict for example::
+
+            config = {k: v for k, v in db.get_config_list()}
+            queries = {k[6:]: v for k, v in db.get_config_list('query.')}
 
         :param prefix: a string by which the keys should be selected
         :type prefix:  str

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 3/6] python: turn get_config_list into a generator
  2017-06-26 23:19     ` David Bremner
                         ` (2 preceding siblings ...)
  2017-12-07 11:40       ` [PATCH 2/6] python: add default arg to get_config_list l-m-h
@ 2017-12-07 11:40       ` l-m-h
  2017-12-07 11:40       ` [PATCH 4/6] test: Add tests for new python bindings l-m-h
                         ` (2 subsequent siblings)
  6 siblings, 0 replies; 18+ messages in thread
From: l-m-h @ 2017-12-07 11:40 UTC (permalink / raw)
  To: notmuch; +Cc: Lucas Hoffmann

[-- Attachment #1: Type: text/plain, Size: 44 bytes --]

This is a multi-part message in MIME format.

[-- Attachment #2: Type: text/plain, Size: 246 bytes --]


This mimics the behaviour of the underlying C function more closely as
it also does not store all values in memory.
---
 bindings/python/notmuch/database.py | 30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0003-python-turn-get_config_list-into-a-generator.patch --]
[-- Type: text/x-patch; name="0003-python-turn-get_config_list-into-a-generator.patch", Size: 2742 bytes --]

diff --git a/bindings/python/notmuch/database.py b/bindings/python/notmuch/database.py
index 54966307..32566620 100644
--- a/bindings/python/notmuch/database.py
+++ b/bindings/python/notmuch/database.py
@@ -690,24 +690,22 @@ class Database(object):
     _config_list_destroy.restype = None
 
     def get_config_list(self, prefix=''):
-        """Return a list of key, value pairs where the start of key matches the
-        given prefix
+        """Return a generator of key, value pairs where the start of key
+        matches the given prefix
 
         Note that only config values that are stored in the database are
         searched and returned.  The config file is not read.  If no `prefix` is
         given all config values are returned.
 
-        This could be used to get all config values or all named queries into a
-        dict for example::
+        This could be used to get all named queries into a dict for example::
 
-            config = {k: v for k, v in db.get_config_list()}
             queries = {k[6:]: v for k, v in db.get_config_list('query.')}
 
         :param prefix: a string by which the keys should be selected
         :type prefix:  str
-        :returns:      all key-value pairs where `prefix` matches the beginning
+        :yields:       all key-value pairs where `prefix` matches the beginning
                        of the key
-        :rtype:        a list of pairs of str
+        :ytype:        pairs of str
         :raises:      :exc:`NotmuchError` in case of failure.
 
         """
@@ -717,13 +715,25 @@ class Database(object):
                                        byref(config_list_p))
         if status != STATUS.SUCCESS:
             raise NotmuchError(status)
-        config_list = []
         while self._config_list_valid(config_list_p):
             key = self._config_list_key(config_list_p).decode('utf-8')
             value = self._config_list_value(config_list_p).decode('utf-8')
-            config_list.append((key, value))
+            yield key, value
             self._config_list_move_to_next(config_list_p)
-        return config_list
+
+    def get_configs(self, prefix=''):
+        """Return a dict of key, value pairs where the start of key matches the
+        given prefix
+
+        :param prefix: a string by which the keys should be selected
+        :type prefix:  str
+        :returns:      all key-value pairs where `prefix` matches the beginning
+                       of the key
+        :rtype:        a dict of str: str
+        :raises:      :exc:`NotmuchError` in case of failure.
+
+        """
+        return dict(self.get_config_list(prefix))
 
     """notmuch_database_set_config"""
     _set_config = nmlib.notmuch_database_set_config

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 4/6] test: Add tests for new python bindings
  2017-06-26 23:19     ` David Bremner
                         ` (3 preceding siblings ...)
  2017-12-07 11:40       ` [PATCH 3/6] python: turn get_config_list into a generator l-m-h
@ 2017-12-07 11:40       ` l-m-h
  2017-12-07 11:40       ` [PATCH 5/6] python: Rename get_config_list to get_configs l-m-h
  2017-12-07 11:40       ` [PATCH 6/6] test: Add test to unset config items with the python bindings l-m-h
  6 siblings, 0 replies; 18+ messages in thread
From: l-m-h @ 2017-12-07 11:40 UTC (permalink / raw)
  To: notmuch; +Cc: Lucas Hoffmann

[-- Attachment #1: Type: text/plain, Size: 44 bytes --]

This is a multi-part message in MIME format.

[-- Attachment #2: Type: text/plain, Size: 220 bytes --]


The tests where adopted from the tests for the corresponding C functions
in test/T590-libconfig.sh.
---
 test/T390-python.sh | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 68 insertions(+)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0004-test-Add-tests-for-new-python-bindings.patch --]
[-- Type: text/x-patch; name="0004-test-Add-tests-for-new-python-bindings.patch", Size: 2436 bytes --]

diff --git a/test/T390-python.sh b/test/T390-python.sh
index a93a7f34..725a00c9 100755
--- a/test/T390-python.sh
+++ b/test/T390-python.sh
@@ -74,4 +74,72 @@ EOF
 notmuch search --sort=oldest-first --output=messages "tučňáččí" | sed s/^id:// > EXPECTED
 test_expect_equal_file EXPECTED OUTPUT
 
+# TODO currently these tests for setting and getting config values are
+# somewhat interdependent.  This is because the config values stored in the
+# database are not cleaned up after each test, so they remain there for the
+# next test.  The ./README file states that this can happen so it seems kind
+# of ok.
+
+test_begin_subtest "set and get config values"
+test_python <<'EOF'
+import notmuch
+db = notmuch.Database(mode=notmuch.Database.MODE.READ_WRITE)
+db.set_config('testkey1', 'testvalue1')
+db.set_config('testkey2', 'testvalue2')
+v1 = db.get_config('testkey1')
+v2 = db.get_config('testkey2')
+print('testkey1 = ' + v1)
+print('testkey2 = ' + v2)
+EOF
+cat <<'EOF' >EXPECTED
+testkey1 = testvalue1
+testkey2 = testvalue2
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "get_config_list with no match returns empty generator"
+test_python <<'EOF'
+import notmuch
+db = notmuch.Database()
+v = db.get_config_list('nonexistent')
+print(list(v) == [])
+EOF
+test_expect_equal "$(cat OUTPUT)" "True"
+
+test_begin_subtest "get_config_list with no arguments returns all pairs"
+test_python <<'EOF'
+import notmuch
+db = notmuch.Database(mode=notmuch.Database.MODE.READ_WRITE)
+db.set_config("zzzafter", "afterval")
+db.set_config("aaabefore", "beforeval")
+v = db.get_config_list()
+for index, keyval in enumerate(v):
+    key, val = keyval
+    print('{}: {} => {}'.format(index, key, val))
+EOF
+cat <<'EOF' >EXPECTED
+0: aaabefore => beforeval
+1: testkey1 => testvalue1
+2: testkey2 => testvalue2
+3: zzzafter => afterval
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "get_config_list prefix is used to match keys"
+test_python <<'EOF'
+import notmuch
+db = notmuch.Database(mode=notmuch.Database.MODE.READ_WRITE)
+db.set_config('testkey1', 'testvalue1')
+db.set_config('testkey2', 'testvalue2')
+v = db.get_config_list('testkey')
+for index, keyval in enumerate(v):
+    key, val = keyval
+    print('{}: {} => {}'.format(index, key, val))
+EOF
+cat <<'EOF' >EXPECTED
+0: testkey1 => testvalue1
+1: testkey2 => testvalue2
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
 test_done

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 5/6] python: Rename get_config_list to get_configs
  2017-06-26 23:19     ` David Bremner
                         ` (4 preceding siblings ...)
  2017-12-07 11:40       ` [PATCH 4/6] test: Add tests for new python bindings l-m-h
@ 2017-12-07 11:40       ` l-m-h
  2017-12-22 21:59         ` David Bremner
  2017-12-07 11:40       ` [PATCH 6/6] test: Add test to unset config items with the python bindings l-m-h
  6 siblings, 1 reply; 18+ messages in thread
From: l-m-h @ 2017-12-07 11:40 UTC (permalink / raw)
  To: notmuch; +Cc: Lucas Hoffmann

[-- Attachment #1: Type: text/plain, Size: 44 bytes --]

This is a multi-part message in MIME format.

[-- Attachment #2: Type: text/plain, Size: 354 bytes --]


The old name has a bit of a feeling of hungarian notation.  Also many
generators in the core are named with the suffix "s" to indicate
iterables: dict.items, dict.keys for example.
---
 bindings/python/notmuch/database.py | 18 ++----------------
 test/T390-python.sh                 | 12 ++++++------
 2 files changed, 8 insertions(+), 22 deletions(-)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0005-python-Rename-get_config_list-to-get_configs.patch --]
[-- Type: text/x-patch; name="0005-python-Rename-get_config_list-to-get_configs.patch", Size: 3382 bytes --]

diff --git a/bindings/python/notmuch/database.py b/bindings/python/notmuch/database.py
index 32566620..fe09b330 100644
--- a/bindings/python/notmuch/database.py
+++ b/bindings/python/notmuch/database.py
@@ -689,7 +689,7 @@ class Database(object):
     _config_list_destroy.argtypes = [NotmuchConfigListP]
     _config_list_destroy.restype = None
 
-    def get_config_list(self, prefix=''):
+    def get_configs(self, prefix=''):
         """Return a generator of key, value pairs where the start of key
         matches the given prefix
 
@@ -699,7 +699,7 @@ class Database(object):
 
         This could be used to get all named queries into a dict for example::
 
-            queries = {k[6:]: v for k, v in db.get_config_list('query.')}
+            queries = {k[6:]: v for k, v in db.get_configs('query.')}
 
         :param prefix: a string by which the keys should be selected
         :type prefix:  str
@@ -721,20 +721,6 @@ class Database(object):
             yield key, value
             self._config_list_move_to_next(config_list_p)
 
-    def get_configs(self, prefix=''):
-        """Return a dict of key, value pairs where the start of key matches the
-        given prefix
-
-        :param prefix: a string by which the keys should be selected
-        :type prefix:  str
-        :returns:      all key-value pairs where `prefix` matches the beginning
-                       of the key
-        :rtype:        a dict of str: str
-        :raises:      :exc:`NotmuchError` in case of failure.
-
-        """
-        return dict(self.get_config_list(prefix))
-
     """notmuch_database_set_config"""
     _set_config = nmlib.notmuch_database_set_config
     _set_config.argtypes = [NotmuchDatabaseP, c_char_p, c_char_p]
diff --git a/test/T390-python.sh b/test/T390-python.sh
index 725a00c9..c6f395e4 100755
--- a/test/T390-python.sh
+++ b/test/T390-python.sh
@@ -97,22 +97,22 @@ testkey2 = testvalue2
 EOF
 test_expect_equal_file EXPECTED OUTPUT
 
-test_begin_subtest "get_config_list with no match returns empty generator"
+test_begin_subtest "get_configs with no match returns empty generator"
 test_python <<'EOF'
 import notmuch
 db = notmuch.Database()
-v = db.get_config_list('nonexistent')
+v = db.get_configs('nonexistent')
 print(list(v) == [])
 EOF
 test_expect_equal "$(cat OUTPUT)" "True"
 
-test_begin_subtest "get_config_list with no arguments returns all pairs"
+test_begin_subtest "get_configs with no arguments returns all pairs"
 test_python <<'EOF'
 import notmuch
 db = notmuch.Database(mode=notmuch.Database.MODE.READ_WRITE)
 db.set_config("zzzafter", "afterval")
 db.set_config("aaabefore", "beforeval")
-v = db.get_config_list()
+v = db.get_configs()
 for index, keyval in enumerate(v):
     key, val = keyval
     print('{}: {} => {}'.format(index, key, val))
@@ -125,13 +125,13 @@ cat <<'EOF' >EXPECTED
 EOF
 test_expect_equal_file EXPECTED OUTPUT
 
-test_begin_subtest "get_config_list prefix is used to match keys"
+test_begin_subtest "get_configs prefix is used to match keys"
 test_python <<'EOF'
 import notmuch
 db = notmuch.Database(mode=notmuch.Database.MODE.READ_WRITE)
 db.set_config('testkey1', 'testvalue1')
 db.set_config('testkey2', 'testvalue2')
-v = db.get_config_list('testkey')
+v = db.get_configs('testkey')
 for index, keyval in enumerate(v):
     key, val = keyval
     print('{}: {} => {}'.format(index, key, val))

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 6/6] test: Add test to unset config items with the python bindings
  2017-06-26 23:19     ` David Bremner
                         ` (5 preceding siblings ...)
  2017-12-07 11:40       ` [PATCH 5/6] python: Rename get_config_list to get_configs l-m-h
@ 2017-12-07 11:40       ` l-m-h
  6 siblings, 0 replies; 18+ messages in thread
From: l-m-h @ 2017-12-07 11:40 UTC (permalink / raw)
  To: notmuch; +Cc: Lucas Hoffmann

[-- Attachment #1: Type: text/plain, Size: 44 bytes --]

This is a multi-part message in MIME format.

[-- Attachment #2: Type: text/plain, Size: 79 bytes --]

---
 test/T390-python.sh | 13 +++++++++++++
 1 file changed, 13 insertions(+)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0006-test-Add-test-to-unset-config-items-with-the-python-.patch --]
[-- Type: text/x-patch; name="0006-test-Add-test-to-unset-config-items-with-the-python-.patch", Size: 630 bytes --]

diff --git a/test/T390-python.sh b/test/T390-python.sh
index c6f395e4..312d61e8 100755
--- a/test/T390-python.sh
+++ b/test/T390-python.sh
@@ -142,4 +142,17 @@ cat <<'EOF' >EXPECTED
 EOF
 test_expect_equal_file EXPECTED OUTPUT
 
+test_begin_subtest "set_config with no value will unset config entries"
+test_python <<'EOF'
+import notmuch
+db = notmuch.Database(mode=notmuch.Database.MODE.READ_WRITE)
+db.set_config('testkey1', '')
+db.set_config('testkey2', '')
+db.set_config("zzzafter", '')
+db.set_config("aaabefore", '')
+v = db.get_configs()
+print(list(v) == [])
+EOF
+test_expect_equal "$(cat OUTPUT)" "True"
+
 test_done

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH 0/6] python: add bindings for notmuch_database_get_config{, _list}
  2017-12-07 11:40       ` [PATCH 0/6] " l-m-h
@ 2017-12-19 11:13         ` David Bremner
  0 siblings, 0 replies; 18+ messages in thread
From: David Bremner @ 2017-12-19 11:13 UTC (permalink / raw)
  To: l-m-h, notmuch; +Cc: Lucas Hoffmann

l-m-h@web.de writes:

> Comming back after a long time (sorry for the wait).
>
> I now changed the binding for notmuch_database_get_config_list into a
> generator.  It is called get_configs in the python bindings (the "s"
> should indicate the iterable/generator nature like for dict.items or
> dict.keys).

Series pushed to master. Thanks for contributing to notmuch.

d

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 5/6] python: Rename get_config_list to get_configs
  2017-12-07 11:40       ` [PATCH 5/6] python: Rename get_config_list to get_configs l-m-h
@ 2017-12-22 21:59         ` David Bremner
  2017-12-22 22:26           ` [PATCH 0/1] " l-m-h
  2017-12-22 22:26           ` [PATCH 1/1] python: Fix method name in docs l-m-h
  0 siblings, 2 replies; 18+ messages in thread
From: David Bremner @ 2017-12-22 21:59 UTC (permalink / raw)
  To: l-m-h, notmuch; +Cc: Lucas Hoffmann

l-m-h@web.de writes:

> The old name has a bit of a feeling of hungarian notation.  Also many
> generators in the core are named with the suffix "s" to indicate
> iterables: dict.items, dict.keys for example.

I think you also need to update

  docs/source/database.rst

At least, that's my interpretation from the sphinx messages I get when I
run

% cd docs && make html

d

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 0/1] Rename get_config_list to get_configs
  2017-12-22 21:59         ` David Bremner
@ 2017-12-22 22:26           ` l-m-h
  2017-12-22 22:26           ` [PATCH 1/1] python: Fix method name in docs l-m-h
  1 sibling, 0 replies; 18+ messages in thread
From: l-m-h @ 2017-12-22 22:26 UTC (permalink / raw)
  To: david; +Cc: Lucas Hoffmann, notmuch

[-- Attachment #1: Type: text/plain, Size: 44 bytes --]

This is a multi-part message in MIME format.

[-- Attachment #2: Type: text/plain, Size: 213 bytes --]


Sorry I overlooked that. Patch coming right up.

Lucas Hoffmann (1):
  python: Fix method name in docs

 bindings/python/docs/source/database.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

-- 
2.15.1

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 1/1] python: Fix method name in docs
  2017-12-22 21:59         ` David Bremner
  2017-12-22 22:26           ` [PATCH 0/1] " l-m-h
@ 2017-12-22 22:26           ` l-m-h
  2017-12-24 14:05             ` David Bremner
  1 sibling, 1 reply; 18+ messages in thread
From: l-m-h @ 2017-12-22 22:26 UTC (permalink / raw)
  To: david; +Cc: Lucas Hoffmann, notmuch

[-- Attachment #1: Type: text/plain, Size: 44 bytes --]

This is a multi-part message in MIME format.

[-- Attachment #2: Type: text/plain, Size: 199 bytes --]


Fix a method rename in the docs that was overlooked in
3444c731d27fd42bbbdaae00af6ca48b4525b03b.
---
 bindings/python/docs/source/database.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0001-python-Fix-method-name-in-docs.patch --]
[-- Type: text/x-patch; name="0001-python-Fix-method-name-in-docs.patch", Size: 379 bytes --]

diff --git a/bindings/python/docs/source/database.rst b/bindings/python/docs/source/database.rst
index f9567949..660de91d 100644
--- a/bindings/python/docs/source/database.rst
+++ b/bindings/python/docs/source/database.rst
@@ -39,7 +39,7 @@
 
    .. automethod:: get_config
 
-   .. automethod:: get_config_list
+   .. automethod:: get_configs
 
    .. automethod:: set_config
 

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/1] python: Fix method name in docs
  2017-12-22 22:26           ` [PATCH 1/1] python: Fix method name in docs l-m-h
@ 2017-12-24 14:05             ` David Bremner
  0 siblings, 0 replies; 18+ messages in thread
From: David Bremner @ 2017-12-24 14:05 UTC (permalink / raw)
  To: l-m-h; +Cc: Lucas Hoffmann, notmuch

l-m-h@web.de writes:

> Fix a method rename in the docs that was overlooked in
> 3444c731d27fd42bbbdaae00af6ca48b4525b03b.

thanks, pushed to master,

d

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2017-12-24 14:05 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-04 17:20 [PATCH 1/2] python: add bindings for notmuch_database_get_config{, _list} l-m-h
2017-06-04 17:20 ` [PATCH 2/2] python: add convenience function to get named queries l-m-h
2017-06-10 11:37   ` David Bremner
2017-06-10 11:10 ` [PATCH 1/2] python: add bindings for notmuch_database_get_config{, _list} David Bremner
2017-06-20 20:06   ` Lucas Hoffmann
2017-06-26 23:19     ` David Bremner
2017-12-07 11:40       ` [PATCH 0/6] " l-m-h
2017-12-19 11:13         ` David Bremner
2017-12-07 11:40       ` [PATCH 1/6] python: add bindings to access config l-m-h
2017-12-07 11:40       ` [PATCH 2/6] python: add default arg to get_config_list l-m-h
2017-12-07 11:40       ` [PATCH 3/6] python: turn get_config_list into a generator l-m-h
2017-12-07 11:40       ` [PATCH 4/6] test: Add tests for new python bindings l-m-h
2017-12-07 11:40       ` [PATCH 5/6] python: Rename get_config_list to get_configs l-m-h
2017-12-22 21:59         ` David Bremner
2017-12-22 22:26           ` [PATCH 0/1] " l-m-h
2017-12-22 22:26           ` [PATCH 1/1] python: Fix method name in docs l-m-h
2017-12-24 14:05             ` David Bremner
2017-12-07 11:40       ` [PATCH 6/6] test: Add test to unset config items with the python bindings l-m-h

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).