]> git.notmuchmail.org Git - notmuch/blob - bindings/python-cffi/notmuch2/_config.py
test/T391-python-cffi
[notmuch] / bindings / python-cffi / notmuch2 / _config.py
1 import collections.abc
2
3 import notmuch2._base as base
4 import notmuch2._capi as capi
5 import notmuch2._errors as errors
6
7
8 __all__ = ['ConfigMapping']
9
10
11 class ConfigIter(base.NotmuchIter):
12
13     def __init__(self, parent, iter_p):
14         super().__init__(
15             parent, iter_p,
16             fn_destroy=capi.lib.notmuch_config_list_destroy,
17             fn_valid=capi.lib.notmuch_config_list_valid,
18             fn_get=capi.lib.notmuch_config_list_key,
19             fn_next=capi.lib.notmuch_config_list_move_to_next)
20
21     def __next__(self):
22         item = super().__next__()
23         return base.BinString.from_cffi(item)
24
25
26 class ConfigMapping(base.NotmuchObject, collections.abc.MutableMapping):
27     """The config key/value pairs stored in the database.
28
29     The entries are exposed as a :class:`collections.abc.MutableMapping` object.
30     Note that setting a value to an empty string is the same as deleting it.
31
32     :param parent: the parent object
33     :param ptr_name: the name of the attribute on the parent which will
34        return the memory pointer.  This allows this object to
35        access the pointer via the parent's descriptor and thus
36        trigger :class:`MemoryPointer`'s memory safety.
37     """
38
39     def __init__(self, parent, ptr_name):
40         self._parent = parent
41         self._ptr = lambda: getattr(parent, ptr_name)
42
43     @property
44     def alive(self):
45         return self._parent.alive
46
47     def _destroy(self):
48         pass
49
50     def __getitem__(self, key):
51         if isinstance(key, str):
52             key = key.encode('utf-8')
53         val_pp = capi.ffi.new('char**')
54         ret = capi.lib.notmuch_database_get_config(self._ptr(), key, val_pp)
55         if ret != capi.lib.NOTMUCH_STATUS_SUCCESS:
56             raise errors.NotmuchError(ret)
57         val = base.BinString.from_cffi(val_pp[0])
58         capi.lib.free(val_pp[0])
59         if val == '':
60             raise KeyError
61         return val
62
63     def __setitem__(self, key, val):
64         if isinstance(key, str):
65             key = key.encode('utf-8')
66         if isinstance(val, str):
67             val = val.encode('utf-8')
68         ret = capi.lib.notmuch_database_set_config(self._ptr(), key, val)
69         if ret != capi.lib.NOTMUCH_STATUS_SUCCESS:
70             raise errors.NotmuchError(ret)
71
72     def __delitem__(self, key):
73         self[key] = ""
74
75     def __iter__(self):
76         """Return an iterator over the config items.
77
78         :raises NullPointerError: If the iterator can not be created.
79         """
80         configlist_pp = capi.ffi.new('notmuch_config_list_t**')
81         ret = capi.lib.notmuch_database_get_config_list(self._ptr(), b'', configlist_pp)
82         if ret != capi.lib.NOTMUCH_STATUS_SUCCESS:
83             raise errors.NotmuchError(ret)
84         return ConfigIter(self._parent, configlist_pp[0])
85
86     def __len__(self):
87         return sum(1 for t in self)