Re: [PATCH v2 2/2] python-cffi: use config_pairs API in ConfigIterator

2022-02-17 Thread David Bremner
Floris Bruynooghe  writes:

> lgtm i think :)

Applied to master.

d
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


Re: [PATCH v2 2/2] python-cffi: use config_pairs API in ConfigIterator

2022-02-17 Thread Floris Bruynooghe
lgtm i think :)

On Wed 16 Feb 2022 at 22:08 -0400, David Bremner wrote:

> This returns all of the config keys with non-empty values, not just
> those that happen to be stored in the database.
> ---
>  bindings/python-cffi/notmuch2/_build.py   | 16 -
>  bindings/python-cffi/notmuch2/_config.py  | 40 +++
>  bindings/python-cffi/tests/test_config.py | 24 --
>  test/T055-path-config.sh  |  1 -
>  4 files changed, 49 insertions(+), 32 deletions(-)
>
> diff --git a/bindings/python-cffi/notmuch2/_build.py 
> b/bindings/python-cffi/notmuch2/_build.py
> index a55b484f..349bb79d 100644
> --- a/bindings/python-cffi/notmuch2/_build.py
> +++ b/bindings/python-cffi/notmuch2/_build.py
> @@ -97,7 +97,7 @@ ffibuilder.cdef(
>  typedef struct _notmuch_string_map_iterator notmuch_message_properties_t;
>  typedef struct _notmuch_directory notmuch_directory_t;
>  typedef struct _notmuch_filenames notmuch_filenames_t;
> -typedef struct _notmuch_config_list notmuch_config_list_t;
> +typedef struct _notmuch_config_pairs notmuch_config_pairs_t;
>  typedef struct _notmuch_indexopts notmuch_indexopts_t;
>  
>  const char *
> @@ -325,18 +325,18 @@ ffibuilder.cdef(
>  notmuch_database_set_config (notmuch_database_t *db, const char *key, 
> const char *value);
>  notmuch_status_t
>  notmuch_database_get_config (notmuch_database_t *db, const char *key, 
> char **value);
> -notmuch_status_t
> -notmuch_database_get_config_list (notmuch_database_t *db, const char 
> *prefix, notmuch_config_list_t **out);
> +notmuch_config_pairs_t *
> +notmuch_config_get_pairs (notmuch_database_t *db, const char *prefix);
>  notmuch_bool_t
> -notmuch_config_list_valid (notmuch_config_list_t *config_list);
> +notmuch_config_pairs_valid (notmuch_config_pairs_t *config_list);
>  const char *
> -notmuch_config_list_key (notmuch_config_list_t *config_list);
> +notmuch_config_pairs_key (notmuch_config_pairs_t *config_list);
>  const char *
> -notmuch_config_list_value (notmuch_config_list_t *config_list);
> +notmuch_config_pairs_value (notmuch_config_pairs_t *config_list);
>  void
> -notmuch_config_list_move_to_next (notmuch_config_list_t *config_list);
> +notmuch_config_pairs_move_to_next (notmuch_config_pairs_t *config_list);
>  void
> -notmuch_config_list_destroy (notmuch_config_list_t *config_list);
> +notmuch_config_pairs_destroy (notmuch_config_pairs_t *config_list);
>  """
>  )
>  
> diff --git a/bindings/python-cffi/notmuch2/_config.py 
> b/bindings/python-cffi/notmuch2/_config.py
> index 29de6495..603fdcbf 100644
> --- a/bindings/python-cffi/notmuch2/_config.py
> +++ b/bindings/python-cffi/notmuch2/_config.py
> @@ -13,27 +13,42 @@ class ConfigIter(base.NotmuchIter):
>  def __init__(self, parent, iter_p):
>  super().__init__(
>  parent, iter_p,
> -fn_destroy=capi.lib.notmuch_config_list_destroy,
> -fn_valid=capi.lib.notmuch_config_list_valid,
> -fn_get=capi.lib.notmuch_config_list_key,
> -fn_next=capi.lib.notmuch_config_list_move_to_next)
> +fn_destroy=capi.lib.notmuch_config_pairs_destroy,
> +fn_valid=capi.lib.notmuch_config_pairs_valid,
> +fn_get=capi.lib.notmuch_config_pairs_key,
> +fn_next=capi.lib.notmuch_config_pairs_move_to_next)
>  
>  def __next__(self):
> -item = super().__next__()
> -return base.BinString.from_cffi(item)
> -
> +# skip pairs whose value is NULL
> +while capi.lib.notmuch_config_pairs_valid(super()._iter_p):
> +val_p = capi.lib.notmuch_config_pairs_value(super()._iter_p)
> +key_p = capi.lib.notmuch_config_pairs_key(super()._iter_p)
> +if key_p == capi.ffi.NULL:
> +# this should never happen
> +raise errors.NullPointerError
> +key = base.BinString.from_cffi(key_p)
> +capi.lib.notmuch_config_pairs_move_to_next(super()._iter_p)
> +if val_p != capi.ffi.NULL and base.BinString.from_cffi(val_p) != 
> "":
> +return key
> +self._destroy()
> +raise StopIteration
>  
>  class ConfigMapping(base.NotmuchObject, collections.abc.MutableMapping):
> -"""The config key/value pairs stored in the database.
> +"""The config key/value pairs loaded from the database, config file,
> +and and/or defaults.
>  
>  The entries are exposed as a :class:`collections.abc.MutableMapping` 
> object.
>  Note that setting a value to an empty string is the same as deleting it.
>  
> +Mutating (deleting or updating values) in the map persists only in
> +the database, which can be shadowed by config files.
> +
>  :param parent: the parent object
>  :param ptr_name: the name of the attribute on the parent which will
> return the memory pointer.  This allows this