3 import notmuch2._base as base
4 import notmuch2._capi as capi
5 import notmuch2._errors as errors
8 __all__ = ['ConfigMapping']
11 class ConfigIter(base.NotmuchIter):
13 def __init__(self, parent, iter_p):
16 fn_destroy=capi.lib.notmuch_config_pairs_destroy,
17 fn_valid=capi.lib.notmuch_config_pairs_valid,
18 fn_get=capi.lib.notmuch_config_pairs_key,
19 fn_next=capi.lib.notmuch_config_pairs_move_to_next)
22 # skip pairs whose value is NULL
23 while capi.lib.notmuch_config_pairs_valid(super()._iter_p):
24 val_p = capi.lib.notmuch_config_pairs_value(super()._iter_p)
25 key_p = capi.lib.notmuch_config_pairs_key(super()._iter_p)
26 if key_p == capi.ffi.NULL:
27 # this should never happen
28 raise errors.NullPointerError
29 key = base.BinString.from_cffi(key_p)
30 capi.lib.notmuch_config_pairs_move_to_next(super()._iter_p)
31 if val_p != capi.ffi.NULL and base.BinString.from_cffi(val_p) != "":
36 class ConfigMapping(base.NotmuchObject, collections.abc.MutableMapping):
37 """The config key/value pairs loaded from the database, config file,
40 The entries are exposed as a :class:`collections.abc.MutableMapping` object.
41 Note that setting a value to an empty string is the same as deleting it.
43 Mutating (deleting or updating values) in the map persists only in
44 the database, which can be shadowed by config files.
46 :param parent: the parent object
47 :param ptr_name: the name of the attribute on the parent which will
48 return the memory pointer. This allows this object to
49 access the pointer via the parent's descriptor and thus
50 trigger :class:`MemoryPointer`'s memory safety.
54 def __init__(self, parent, ptr_name):
56 self._ptr = lambda: getattr(parent, ptr_name)
60 return self._parent.alive
65 def __getitem__(self, key):
66 if isinstance(key, str):
67 key = key.encode('utf-8')
68 val_pp = capi.ffi.new('char**')
69 ret = capi.lib.notmuch_database_get_config(self._ptr(), key, val_pp)
70 if ret != capi.lib.NOTMUCH_STATUS_SUCCESS:
71 raise errors.NotmuchError(ret)
72 val = base.BinString.from_cffi(val_pp[0])
73 capi.lib.free(val_pp[0])
78 def __setitem__(self, key, val):
79 if isinstance(key, str):
80 key = key.encode('utf-8')
81 if isinstance(val, str):
82 val = val.encode('utf-8')
83 ret = capi.lib.notmuch_database_set_config(self._ptr(), key, val)
84 if ret != capi.lib.NOTMUCH_STATUS_SUCCESS:
85 raise errors.NotmuchError(ret)
87 def __delitem__(self, key):
91 """Return an iterator over the config items.
93 :raises NullPointerError: If the iterator can not be created.
95 config_pairs_p = capi.lib.notmuch_config_get_pairs(self._ptr(), b'')
96 if config_pairs_p == capi.ffi.NULL:
98 return ConfigIter(self._parent, config_pairs_p)
101 return sum(1 for t in self)