Pydantic Merge
Merge configuration values with the validation and type safety of Pydantic.
pydantic-merge adds a model_merge() method to a Pydantic model. Values in
nested BaseModel fields are merged recursively; ordinary values are
overwritten by the new value.
Installation
pip install pydantic-merge pydantic
The package supports Python 3.13 and later.
Usage
Import BaseModel from pydantic_merge instead of directly from Pydantic:
import pydantic
from pydantic_merge import BaseModel
class DatabaseConfig(BaseModel):
host: str = "localhost"
port: int = 5432
class AppConfig(BaseModel):
debug: bool = False
database: DatabaseConfig = DatabaseConfig()
tags: list[str] = pydantic.Field(default_factory=list)
labels: dict[str, str] = pydantic.Field(default_factory=dict)
base = AppConfig(
debug=False,
database=DatabaseConfig(host="db.example.com"),
tags=["production"],
labels={"team": "platform"},
)
merged = base.model_merge(
{
"debug": True,
"database": {"port": 5433},
"tags": ["canary"],
"labels": {"region": "eu-west-1"},
}
)
assert merged.debug is True
assert merged.database.host == "db.example.com"
assert merged.database.port == 5433
assert merged.tags == ["canary"]
assert merged.labels == {"region": "eu-west-1"}
model_merge() accepts either another compatible model or a dictionary:
patch = AppConfig(database={"port": 5434})
merged = base.model_merge(patch)
The result is a new instance. The original model is not modified, and the merged values are validated by Pydantic.
Using the mixin with Pydantic
If you want to keep importing BaseModel from Pydantic, add
MergeableExtension as a second base class:
import pydantic
from pydantic_merge import MergeableExtension
class DatabaseConfig(pydantic.BaseModel):
host: str = "localhost"
port: int = 5432
class AppConfig(pydantic.BaseModel, MergeableExtension):
database: DatabaseConfig = DatabaseConfig()
config = AppConfig.model_validate({"database": {"port": 5433}})
assert config.database.host == "localhost"
assert config.database.port == 5433
Place pydantic.BaseModel before MergeableExtension in the class
definition. This form provides the same recursive validation and
model_merge() behavior as importing BaseModel from pydantic_merge.
Merge behavior
- Nested
pydantic_merge.BaseModelfields are merged recursively. - Fields supplied by the override replace the corresponding base value.
- Fields omitted from the override retain the base value or model default.
- Lists are replaced as a whole; their items are not merged.
- Plain dictionaries are replaced as a whole; their keys are not merged.
- A nested model can be overridden with a dictionary containing only the fields that should change.
The top-level model must either inherit from pydantic_merge.BaseModel or use
MergeableExtension alongside pydantic.BaseModel to provide the
model_merge() method. Nested Pydantic BaseModel fields are recognized and
can be merged recursively; lists and dictionaries remain replacement values.
Errors
PydanticMergeError is raised when MergeableExtension is used with an
unsupported type. Normal validation failures are raised by Pydantic as
ValidationError.
Development
Install the development environment and run the tests with uv:
uv sync --group test --group stubs
uv run pytest -v
License
This project is licensed under the MIT License. See LICENSE.
Metadata
Release files for pydantic-merge 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pydantic_merge-0.1.2.tar.gz | 4.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pydantic_merge-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 8.8 kB
Release files / pydantic_merge-0.1.2.tar.gz
| Download URL | pydantic_merge-0.1.2.tar.gz |
|---|---|
| Size | 4.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7d41e29188a93a6946e8f17dec41d949ad380d0eb571a1ffa24a7fd48337990a
|
|
BLAKE2b-256 checksum How to use checksums |
3b5276269c571816cc26ab7701f6499d0ee3e13943222847de667be5cb22b03f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Aug 28, 2026.
Transparency logRelease files / pydantic_merge-0.1.2-py3-none-any.whl
| Download URL | pydantic_merge-0.1.2-py3-none-any.whl |
|---|---|
| Size | 4.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6d079ab19f88e9b6c74668802cb7f7e8da0b2d78387b8bf9b3cfdf88ba5fb6cc
|
|
BLAKE2b-256 checksum How to use checksums |
e820e5056261c9537311b7c67762ea3ac8299a36df621953ab4e3ea7aa64cd78
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Aug 28, 2026.
Transparency log