DeepChainMap
A recursive subclass of collections.ChainMap.
Installation
python -m pip install deep-chainmap
Usage
The canonical use case for collections.ChainMap is to aggregate configuration
data from layered mapping (basically dictionaries) sources. However, it is not
suited for non-flat (nested) mappings, since the lookup mechanism only works for
the top level of a mapping.
deep_chainmap.DeepChainMap provides a simple solution to this problem by making
recurive lookups in arbitrarily deeply nested mappings. Let's illustrate this
with a simple example. We will simulate 3 layers of mapping, and pretend they
were obtained from different sources (a default configuration, a configuration
file and parameters configured at runtime).
from deep_chainmap import DeepChainMap
default_layer = {
"architecture": "gpu",
"logging_level": "warning",
"solver": "RK4",
"database": {
"url": "unset",
"keep_in_sync": False,
},
"mesh": {
"type": "rectangular",
"resolution": {
"x": {
"npoints": 100,
"spacing": "linear",
},
"y": {
"npoints": 100,
"spacing": "linear",
},
"z": {
"npoints": 100,
"spacing": "linear",
},
},
},
}
config_file_layer = {
"architecture": "cpu",
"mesh": {
"resolution": {
"x": {
"spacing": "log",
},
"z": {
"npoints": 1,
},
},
},
}
runtime_layer = {
"logging_level": "debug",
"database": {
"url": "https://my.database.api",
"keep_in_sync": True
},
}
# now building a DeepChainMap
cm = DeepChainMap(runtime_layer, config_file_layer, default_layer)
Now when a single parameter is requested, it is looked up in each layer until a
value is found, by order of insertion. Here the runtime_layer takes priority
over the config_file_layer, which in turns takes priority over the
default_layer.
>>> cm["logging_level"]
'debug'
>>> cm["mesh"]["resolution"]["x"]["spacing"]
'log'
>>> cm["mesh"]["resolution"]["x"]["npoints"]
100
Note that submappings at any level can be retrieved as new
DeepChainMap instances
>>> cm["mesh"]
DeepChainMap({'resolution': {'x': {'spacing': 'log'}, 'z': {'npoints': 1}}},
{'resolution': {'x': {'npoints': 100, 'spacing': 'linear'},
'y': {'npoints': 100, 'spacing': 'linear'},
'z': {'npoints': 100, 'spacing': 'linear'}},
'type': 'rectangular'})
The other important feature is the to_dict method, which constructs a builtin
dict from a DeepChainMap
>>> cm.to_dict()
{
'architecture': 'cpu',
'logging_level': 'debug',
'solver': 'RK4',
'database': {
'url': 'https://my.database.api',
'keep_in_sync': True
},
'mesh': {
'type': 'rectangular',
'resolution': {
'x': {'npoints': 100, 'spacing': 'log'},
'y': {'npoints': 100, 'spacing': 'linear'},
'z': {'npoints': 1, 'spacing': 'linear'}
}
}
}
An important implication is that the DeepChainMap class enables a very simple,
functional implementation of a depth-first dict-merge algorithm as
from deep_chainmap import DeepChainMap
def depth_first_merge(*mappings) -> dict:
return DeepChainMap(*mappings).to_dict()
Limitations
As the standard collections.ChainMap class, DeepChainMap does not, by
design, perform any kind of data validation. Rather, it is assumed that the
input mappings are similar in structure, meaning that a key which maps to a dict
in one of the input mappings is assumed to map to dict instances as well in
every other input mapping. Use the excellent
schema library or similar projects for this
task.
⚠️ An important difference with collections.ChainMap is that, when
setting a (key, value) pair in a DeepChainMap instance, the new value is
stored in the first mapping which already contains the parent map. For example
if we run
>>> cm["mesh"]["resolution"]["x"]["spacing"] = "exp"
The affected layer is config_file_layer rather than runtime_layer, as one
can see
>>> config_file_layer
{
'architecture': 'cpu',
'mesh': {
'resolution': {
'x': {'spacing': 'exp'},
'z': {'npoints': 1}
}
}
}
>>> runtime_layer
{
'logging_level': 'debug',
'database': {
'url': 'https://my.database.api',
'keep_in_sync': True
}
}
This behaviour is a side effect on an implementation detail and subject to change in a future version. Please do not rely on it.
Metadata
Release files for deep-chainmap 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| deep_chainmap-0.2.0.tar.gz | 4.4 kB | With provenance | Details for deep_chainmap-0.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| deep_chainmap-0.2.0-py3-none-any.whl | Python 3 | none | any | Details for deep_chainmap-0.2.0-py3-none-any.whl |
Total release size: 8.7 kB
Release files / deep_chainmap-0.2.0.tar.gz
| Download URL | deep_chainmap-0.2.0.tar.gz |
|---|---|
| Size | 4.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
96b0a0e861b18eafd8dedd5cd47a49b9a3fe5d5bd5ace701e5a55a7a6e44fc8f
|
|
BLAKE2b-256 checksum How to use checksums |
6e3e91e085cd7dfc7bc24df20c482291b16f4e6287a8b60b9a1efaf8fd8ead0f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 7, 2026.
Transparency logRelease files / deep_chainmap-0.2.0-py3-none-any.whl
| Download URL | deep_chainmap-0.2.0-py3-none-any.whl |
|---|---|
| Size | 4.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2a979383ca85c4cfee35bd34984e51b2ec69d66efa81df1eae7f99e4dfb35330
|
|
BLAKE2b-256 checksum How to use checksums |
2f8baccbe310f889ca78dde020113542d54f9b31ec8d5f6a119080d9e10eab93
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 7, 2026.
Transparency logSecurity for deep-chainmap 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for deep_chainmap-0.2.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 7, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.