python-configuration
python-configuration copied to clipboard
Bug: update() broken for mapping-like objects
To reproduce:
import collections
conf = Configuration({})
data = collections.ChainMap({"abc": {"def": "ghi"}})
conf.update(data)
print(conf["abc.def"])
If data is a plain dict or a Configuration object, conf["abc.def"] will give "ghi". However, if it's a mapping-like object, it crashes:
In [60]: c['foo.abc']
Traceback (most recent call last):
File "/Users/diegoargueta/.pyenv/versions/aircraft/lib/python3.7/site-packages/IPython/core/interactiveshell.py", line 3524, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-60-e7c3c391a86e>", line 1, in <module>
c['abc.def']
File "/Users/diegoargueta/.pyenv/versions/3.7.8/envs/aircraft/lib/python3.7/site-packages/config/configuration.py", line 155, in __getitem__
raise KeyError(item)
KeyError: 'abc.def'
Your problem is in _flatten_dict(); you need to change
nested = {k for k, v in d.items() if isinstance(v, (dict, Configuration))}
to
nested = {k for k, v in d.items() if isinstance(v, Mapping)}
I don't have time to test it but I believe you'll run into this problem with as_attrdict() which also compares against dict. Use Mapping or MutableMapping as needed instead, and this will work as expected.