Metadata-Version: 2.4
Name: philiprehberger-dict-merge
Version: 0.1.8
Summary: Deep merge dictionaries safely with conflict resolution
Project-URL: Homepage, https://github.com/philiprehberger/py-dict-merge#readme
Project-URL: Repository, https://github.com/philiprehberger/py-dict-merge
Project-URL: Issues, https://github.com/philiprehberger/py-dict-merge/issues
Project-URL: Changelog, https://github.com/philiprehberger/py-dict-merge/blob/main/CHANGELOG.md
Author: Philip Rehberger
License-Expression: MIT
License-File: LICENSE
Keywords: deep,dict,dictionary,merge,recursive
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown

# philiprehberger-dict-merge

[![Tests](https://github.com/philiprehberger/py-dict-merge/actions/workflows/publish.yml/badge.svg)](https://github.com/philiprehberger/py-dict-merge/actions/workflows/publish.yml)
[![PyPI version](https://img.shields.io/pypi/v/philiprehberger-dict-merge.svg)](https://pypi.org/project/philiprehberger-dict-merge/)
[![License](https://img.shields.io/github/license/philiprehberger/py-dict-merge)](LICENSE)

Deep merge dictionaries safely with conflict resolution.

## Installation

```bash
pip install philiprehberger-dict-merge
```

## Usage

```python
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
```

## 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 |
| `MergeConflictError` | Raised by `Strategy.ERROR` — has `.key`, `.left`, `.right` attributes |
| List strategies: `"replace"`, `"append"`, `"unique"`, `"concat"` | List merge modes |


## Development

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

## License

MIT
