Deepmerge
deepmerge is a Python library providing a toolset for deeply merging Python dictionaries, handling nested structures, lists, and various data types with configurable strategies. The current stable version is 2.0, released recently with Python 3.8+ support. The library maintains a stable API, with new versions focusing on type hints, bug fixes, and minor enhancements.
Warnings
- breaking Deepmerge v2.0 dropped support for Python versions older than 3.8. Projects still using Python 3.7 or earlier must pin `deepmerge<2.0`.
- breaking Version 2.0 introduced extensive type hinting. While this generally improves static analysis, if you have custom merge strategies or logic that relied on implicit type coercions or incorrect type assumptions, your code might now fail type checks or behave differently when used with type-aware tools like MyPy.
- gotcha The default `always_merger.merge(destination, source1, source2, ...)` modifies the `destination` dictionary in-place. If you intend to preserve the original `destination` dictionary, you must provide a copy (e.g., `always_merger.merge({}, original_dict, new_data)` or `always_merger.merge(copy.deepcopy(original_dict), new_data)`).
- gotcha The default list merging strategy for `always_merger` is `list_extend_strategy`, which appends elements from the source list to the destination list. If you expect lists to be overwritten/replaced or merged differently, you need to configure a custom `Merger` instance.
Install
-
pip install deepmerge
Imports
- always_merger
from deepmerge import always_merger
- Merger
from deepmerge import Merger
Quickstart
from deepmerge import always_merger
dict1 = {
"name": "Alice",
"settings": {"theme": "dark", "notifications": True},
"tags": ["user", "admin"]
}
dict2 = {
"name": "Bob",
"settings": {"notifications": False, "language": "en"},
"tags": ["active"]
}
# By default, always_merger modifies the first dict passed (or a copy).
# To keep dict1 unchanged, merge into an empty dict or a deep copy of dict1.
merged_dict = always_merger.merge({}, dict1, dict2)
print(merged_dict)
# Expected output for tags: ['user', 'admin', 'active'] (default list_extend_strategy)
# Expected output for settings: {'theme': 'dark', 'notifications': False, 'language': 'en'}