python-configuration icon indicating copy to clipboard operation
python-configuration copied to clipboard

Bug: update() broken for mapping-like objects

Open dargueta opened this issue 3 years ago • 0 comments

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.

dargueta avatar May 25 '22 18:05 dargueta