Merge policies
This guide introduces combining two configuration instances with merge(), and
how to control that with Meta.merge and per-field merge=.
You should already know ConfigurationObj, fields, and Meta (guides 101–105).
Why merge?
Typical need: start from defaults (or a base file), then apply an overlay (environment, CLI, second file) without rewriting the whole tree by hand.
from superconf import ConfigurationObj, FieldInt, FieldList, FieldString
class AppConfig(ConfigurationObj):
name = FieldString(default="app")
workers = FieldInt(default=2)
tags = FieldList(default=[])
base = AppConfig(value={"name": "api", "tags": ["core"]})
overlay = AppConfig(value={"workers": 8, "tags": ["prod"]})
merged = base.merge(overlay)
print(merged.get_value())
# {'name': 'api', 'workers': 8, 'tags': ['core', 'prod']}
Notes:
merge()returns a new object;baseandoverlaystay unchanged.- Scalars use policy
overrideby default (right wins when set). - Lists (
FieldList) use policyappendby default.
Declaring a policy on Meta
Meta.merge sets the policy for this container (how it combines with a peer
of the same kind):
from superconf import MergeStrategy
class AppConfig(ConfigurationObj):
class Meta:
merge = MergeStrategy.OVERRIDE # default for dict/obj; can omit
name = FieldString(default="app")
Strings work the same: merge = "override".
Overriding per field
Field kwargs beat Meta (same precedence as cast):
class AppConfig(ConfigurationObj):
class Meta:
merge = "override"
# Stay frozen when parent deep-merges
build_id = FieldInt(default=0, merge=MergeStrategy.KEEP)
name = FieldString(default="app")
tags = FieldList(default=[], merge="replace") # old-style full replace
Strategy cheat sheet
| Kind | Default | Allowed |
|---|---|---|
| Scalar | override |
override, override_non_null, keep |
| Dict / Obj | override |
override, replace, override_present, override_absent, keep |
| List | append |
append, prepend, replace, keep |
Full tables and recipes: merging_configurations.md.
Migration note (lists)
Before merge policies, a list field that was set on the right replaced the
left list. That behavior is merge="replace" now. The new default is append.
Next steps
- How-to recipes: merging_configurations.md
- Internals / copy: merge_and_copy.md
- Previous guide: 105_meta_and_casting.md