Read-only ChainMap of dictionaries

I need to create ChainMap from few dictionaries but I want to prevent accidental modifications of the dictionaries through the ChainMap. I see two obvious solutions using MappingProxyType:

import collections
import types

dict1 = {'a': 1, 'b': 2,}
dict2 = {'a': 11, 'b': 12, 'c': 13}

cm1 = collections.ChainMap(types.MappingProxyType({}), dict1, dict2)
print(dict(cm1), cm1)

cm2 = types.MappingProxyType(collections.ChainMap(dict1, dict2))
print(dict(cm2), cm2)
{'a': 1, 'b': 2, 'c': 13} ChainMap(mappingproxy({}), {'a': 1, 'b': 2}, {'a': 11, 'b': 12, 'c': 13})
{'a': 1, 'b': 2, 'c': 13} ChainMap({'a': 1, 'b': 2}, {'a': 11, 'b': 12, 'c': 13})

Which one should I prefer? Which one is more readable? Is there a better solution?

Currently I prefer the first one, because I can still access the ChainMap attributes if I need them - like cm1.maps.

Is it possible that ChainMap in the standard library would be extended to accept a kwarg to disable write operations?

:weary:
It is becoming complicated and less readable with type annotations:

Excerpt from my real code:

        self.statements = ChainMap(
                cast(MutableMapping, MappingProxyType({})),
                self.statements_time, self.statements_interval)

How about this one from Raymond Hettinger

?

1 Like

Thank you for the example. I will see if I add something like this into my utility library. At this moment I need it just for one variable so I am using the solution from my previous post.

Maybe I will later ask on Ideas if it is viable to extend standard library’s collections.ChainMap to:

ChainMap(*maps, read_only=False)