Skip to main content

Deep merge dictionaries safely with conflict resolution.

Project description

philiprehberger-dict-merge

Tests PyPI version Last updated

Deep merge dictionaries safely with conflict resolution.

Installation

pip install philiprehberger-dict-merge

Usage

from philiprehberger_dict_merge import merge, Strategy

base = {"db": {"host": "localhost", "port": 5432}, "debug": False}
override = {"db": {"port": 3306, "name": "mydb"}, "debug": True}

merge(base, override)
# {"db": {"host": "localhost", "port": 3306, "name": "mydb"}, "debug": True}

# Multiple dicts
merge(defaults, config_file, env_overrides)

# Keep first value on conflict
merge(a, b, strategy=Strategy.KEEP_FIRST)

# Append lists instead of replacing
merge(a, b, list_strategy="append")

# Raise on conflict
from philiprehberger_dict_merge import MergeConflictError

try:
    merge({"key": 1}, {"key": 2}, strategy=Strategy.ERROR)
except MergeConflictError as e:
    print(e.key)   # "key"
    print(e.left)  # 1
    print(e.right) # 2

# Custom resolution per key
merge(
    {"a": 1, "b": 5},
    {"a": 4, "b": 2},
    strategy=Strategy.CALLBACK,
    on_conflict=lambda key, left, right: max(left, right),
)
# {"a": 4, "b": 5}

Flatten and unflatten

Convert between nested dicts and dot-notation flat dicts. Useful when merging config that arrives in different shapes.

from philiprehberger_dict_merge import flatten, unflatten

flatten({"db": {"host": "x", "port": 5432}})
# {"db.host": "x", "db.port": 5432}

unflatten({"db.host": "x", "db.port": 5432})
# {"db": {"host": "x", "port": 5432}}

# Round-trip
unflatten(flatten({"a": {"b": {"c": 1}}})) == {"a": {"b": {"c": 1}}}

API

Function / Class Description
merge(*dicts, strategy=Strategy.REPLACE, list_strategy="replace") Deep merge
Strategy.REPLACE Later values win (default)
Strategy.KEEP_FIRST Earlier values win
Strategy.ERROR Raise on conflict
Strategy.CALLBACK Resolve conflicts via on_conflict(key, left, right)
MergeConflictError Raised by Strategy.ERROR — has .key, .left, .right attributes
List strategies: "replace", "append", "unique", "concat" List merge modes
flatten(d, sep=".") Flatten a nested dict into separator-joined keys
unflatten(d, sep=".") Reverse of flatten — expand separator-joined keys into nested dicts

Development

pip install -e .
python -m pytest tests/ -v

Support

If you find this project useful:

Star the repo

🐛 Report issues

💡 Suggest features

❤️ Sponsor development

🌐 All Open Source Projects

💻 GitHub Profile

🔗 LinkedIn Profile

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

philiprehberger_dict_merge-0.3.0.tar.gz (7.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

philiprehberger_dict_merge-0.3.0-py3-none-any.whl (5.8 kB view details)

Uploaded Python 3

File details

Details for the file philiprehberger_dict_merge-0.3.0.tar.gz.

File metadata

File hashes

Hashes for philiprehberger_dict_merge-0.3.0.tar.gz
Algorithm Hash digest
SHA256 8f8f181a05864104c6edf778ff659f1f573791015b41855b5ec2312ac64b0665
MD5 b885c34c380a90d3050754661c11712c
BLAKE2b-256 0f1d2224f2e71415ff7ca5d981d91b410662ea2a3edfbb615c7951ea13057e49

See more details on using hashes here.

File details

Details for the file philiprehberger_dict_merge-0.3.0-py3-none-any.whl.

File metadata

File hashes

Hashes for philiprehberger_dict_merge-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3eafc990d7f135b42449f94f3703d1f13e9c8411d56c6b5eeadcb4fb0051a548
MD5 85bdf1aa7bd3e4c7317fc5eb7693e849
BLAKE2b-256 d3f7d636d7f129ede0a3aa5e017efdf2169b68adb391fb170f8a9b1575b27eed

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page