mergedeep

raw JSON →
1.3.4 verified Tue May 12 auth: no python install: verified quickstart: verified

mergedeep is a Python library providing a deep merge function for dictionaries and other mutable mappings. It offers flexible strategies for handling conflicts, including replacement (default), additive merging for collections like lists, and type-safe replacement. The current version is 1.3.4, and the library is actively maintained with regular releases.

pip install mergedeep
error ModuleNotFoundError: No module named 'mergedeep'
cause The 'mergedeep' package is not installed in the Python environment.
fix
Install the package using pip: 'pip install mergedeep'.
error ImportError: cannot import name 'merge' from 'mergedeep'
cause The 'mergedeep' package is not installed or the import statement is incorrect.
fix
Ensure the package is installed and use the correct import statement: 'from mergedeep import merge'.
error TypeError: destination type: <class 'list'> differs from source type: <class 'set'> for key: "key"
cause Attempting a typesafe merge with mismatched types between destination and source values.
fix
Ensure that the destination and source values are of the same type when using typesafe merge strategies.
error TypeError: Cannot merge type <class 'set'> with <class 'list'> using strategy TYPESAFE_REPLACE.
cause When using `Strategy.TYPESAFE_REPLACE`, `mergedeep` encounters a conflict where a key exists in both dictionaries but with values of incompatible types (e.g., a set and a list), and `TYPESAFE_REPLACE` explicitly prevents such type mismatches.
fix
from mergedeep import merge, Strategy dst = {"key": [1, 2]} src = {"key": {"a", "b"}} # Example: trying to merge a set into a list key # To resolve, either ensure types are compatible or use a different strategy: # Option 1: Adjust source type if possible # src = {"key": [3, 4]} # merge(dst, src, strategy=Strategy.TYPESAFE_REPLACE) # Option 2: Use Strategy.REPLACE to overwrite with the new type merge(dst, src, strategy=Strategy.REPLACE) print(dst) # Output: {'key': {'a', 'b'}} # Option 3: Use Strategy.ADDITIVE to combine collections if applicable # This example still raises TypeError because set and list are incompatible for ADDITIVE # If both were lists, ADDITIVE would extend the list. # dst = {"key": [1, 2]} # src = {"key": [3, 4]} # merge(dst, src, strategy=Strategy.ADDITIVE) # print(dst) # Output: {'key': [1, 2, 3, 4]}
error TypeError: cannot pickle '_thread.lock' object
cause `mergedeep` uses `deepcopy` internally for nested mutable objects, and one of the objects within your dictionaries is not picklable (e.g., a thread lock, file handle, or other non-serializable object).
fix
Ensure that all objects within the dictionaries you are merging are picklable. If an object is inherently not picklable, you must remove it from the dictionaries before calling mergedeep.merge or implement custom pre-processing to handle such types.
gotcha By default, `mergedeep.merge` modifies the first dictionary (destination) in-place. If you need to preserve the original destination dictionary, pass an empty dictionary as the first argument to `merge`.
fix To prevent mutation, use `merged_dict = merge({}, original_dict, *sources)`.
gotcha The default merge strategy (`Strategy.REPLACE`) for lists, tuples, and sets is to replace the destination collection with the source collection. This differs from some other deep merge implementations that might concatenate or union lists by default.
fix If you intend to combine (e.g., concatenate or union) collections, explicitly use `strategy=Strategy.ADDITIVE`.
gotcha Using `Strategy.TYPESAFE_REPLACE` will raise a `TypeError` if the types of corresponding values in the destination and source dictionaries are different. This can be unexpected if you rely on implicit replacement even when types mismatch.
fix Ensure that types are consistent when using `Strategy.TYPESAFE_REPLACE`, or use `Strategy.REPLACE` for more permissive type handling during replacement.
python os / libc status wheel install import disk
3.10 alpine (musl) wheel - 0.01s 17.8M
3.10 alpine (musl) - - 0.02s 17.8M
3.10 slim (glibc) wheel 1.4s 0.01s 18M
3.10 slim (glibc) - - 0.01s 18M
3.11 alpine (musl) wheel - 0.02s 19.7M
3.11 alpine (musl) - - 0.04s 19.7M
3.11 slim (glibc) wheel 1.5s 0.02s 20M
3.11 slim (glibc) - - 0.02s 20M
3.12 alpine (musl) wheel - 0.01s 11.6M
3.12 alpine (musl) - - 0.02s 11.6M
3.12 slim (glibc) wheel 1.4s 0.01s 12M
3.12 slim (glibc) - - 0.01s 12M
3.13 alpine (musl) wheel - 0.01s 11.3M
3.13 alpine (musl) - - 0.02s 11.2M
3.13 slim (glibc) wheel 1.4s 0.01s 12M
3.13 slim (glibc) - - 0.01s 12M
3.9 alpine (musl) wheel - 0.01s 17.3M
3.9 alpine (musl) - - 0.01s 17.3M
3.9 slim (glibc) wheel 1.7s 0.01s 18M
3.9 slim (glibc) - - 0.01s 18M

Demonstrates basic deep merging using the default REPLACE strategy and an example of the ADDITIVE strategy for collections. It shows both non-mutating and mutating merge patterns.

from mergedeep import merge, Strategy

a = {'keyA': 1, 'nested': {'x': 10, 'list_data': [1, 2]}}
b = {'keyB': 2, 'nested': {'y': 20, 'list_data': [3, 4]}}
c = {'keyC': 3, 'nested': {'x': 100, 'new_list': [5]}}

# 1. Merge into a new dictionary (non-mutating)
merged_new = merge({}, a, b, c)
print(f"Merged into new: {merged_new}")
# Expected: {'keyA': 1, 'nested': {'x': 100, 'list_data': [3, 4], 'y': 20, 'new_list': [5]}, 'keyB': 2, 'keyC': 3}

# 2. Merge into an existing dictionary (mutating 'a')
merge(a, b, c)
print(f"Merged into existing 'a': {a}")
# Expected: {'keyA': 1, 'nested': {'x': 100, 'list_data': [3, 4], 'y': 20, 'new_list': [5]}, 'keyB': 2, 'keyC': 3}

# 3. Merging with an additive strategy for lists
dst_additive = {'items': [1, 2], 'counts': {'a': 1}}
src_additive = {'items': [3, 4], 'counts': {'b': 1}}
merged_additive = merge({}, dst_additive, src_additive, strategy=Strategy.ADDITIVE)
print(f"Merged with ADDITIVE strategy: {merged_additive}")
# Expected: {'items': [1, 2, 3, 4], 'counts': {'a': 1, 'b': 1}}