Layer request defaults with ChainMap

Layer request defaults with ChainMap

Author: Batu. AI assistance was used to draft this article.

collections.ChainMap supplies a single mapping-style view over configuration layers without first merging them. Put the most specific request mapping first, followed by service-level settings and baseline defaults. A lookup searches in that order, so the request’s timeout of 5 wins over the default 30; the service layer provides both retries and region. The three printed values make each source of resolution concrete.

The later assignment, settings["retries"] = 1, is an important detail: ChainMap writes only to its first mapping. The assertion verifies that request gains the override while service["retries"] stays 4. This makes the front map a useful per-request overlay: it records decisions local to the request without mutating reusable layers. Underlying mappings are held by reference, so a later mutation to one of them is visible through the chain.

This is not a deep-merge structure. If a key maps to a nested dictionary, ChainMap chooses one entire nested dictionary rather than combining its fields. Missing lookups still raise KeyError, just as for a normal mapping. Also avoid assuming iteration has lookup precedence: iteration is defined by scanning the underlying mappings in a different direction. Convert to dict(settings) only when a flattened snapshot is actually needed. ChainMap was added in Python 3.3.

Source: Python ChainMap documentation.

from collections import ChainMap

defaults = {"timeout": 30, "retries": 2, "region": "baseline"}
service = {"retries": 4, "region": "zone-a"}
request = {"timeout": 5}
settings = ChainMap(request, service, defaults)

assert settings["timeout"] == 5
assert settings["retries"] == 4
assert settings["region"] == "zone-a"

print("timeout:", settings["timeout"])
print("retries:", settings["retries"])
print("region:", settings["region"])

settings["retries"] = 1
assert request == {"timeout": 5, "retries": 1}
assert service["retries"] == 4
print("request:", request)

Expected stdout

timeout: 5
retries: 4
region: zone-a
request: {'timeout': 5, 'retries': 1}

Comments

Popular posts from this blog

Compare Two Text Files in Python Without Modifying Them

Seven CSV Quality Checks to Run Before Importing Data

Explain why SQLite transactions cannot make an HTTP call atomic