python-box dot-access config: frozen boxes, defaults and YAML/JSON roundtrip: working versions (tested 2026-10-16)
Build dot-access config objects with python-box, deep-merge overrides and defaults, take frozen read-only views, then convert back to plain dicts and round-trip through YAML and JSON.
passed6 passed · 0 failed2026-10-16 21:57 UTC- Status
- passed
- Last passed
- 2026-10-16 21:57 UTC
- Tests
- 6 / 6
- Language
- Python
- Runtime
- Python 3.13.16
uv venv -q .venv && uv pip install -q --python .venv/bin/python -r requirements.txt .venv/bin/python -m pytest -q
Python 3.13.16 linux 6.17.0-1022-azure x64 runner: github-actions 38972656245
The code
Exactly the files that passed. Your agent can pull them with get_recipe("python-box-dot-access-config") (install), or see them on GitHub.
python-box==7.4.1 PyYAML==6.0.3 pytest==9.1.1
from __future__ import annotations
from box import Box
DEFAULTS: dict = {
"service": {"name": "api", "port": 8080, "debug": False},
"db": {"host": "localhost", "port": 5432},
"features": ["metrics"],
}
def load_config(overrides: dict | None = None, *, frozen: bool = False) -> Box:
cfg = Box(DEFAULTS, box_dots=True, default_box=True, default_box_attr=None)
cfg.merge_update(overrides or {})
if frozen:
return Box(cfg.to_dict(), box_dots=True, frozen_box=True)
return cfg
def to_plain(cfg: Box) -> dict:
return cfg.to_dict()
def to_yaml(cfg: Box) -> str:
return Box(_lists(cfg.to_dict()), box_dots=True).to_yaml()
def from_yaml(text: str, *, frozen: bool = False) -> Box:
return Box.from_yaml(text, box_dots=True, frozen_box=frozen)
def to_json(cfg: Box) -> str:
return cfg.to_json()
def from_json(text: str, *, frozen: bool = False) -> Box:
return Box.from_json(text, box_dots=True, frozen_box=frozen)
def _lists(value):
# frozen boxes hold tuples, which dump as !!python/tuple and choke SafeLoader
if isinstance(value, dict):
return {k: _lists(v) for k, v in value.items()}
if isinstance(value, (list, tuple)):
return [_lists(v) for v in value]
return value
import pytest
import yaml
from box import Box, BoxError
from config import from_json, from_yaml, load_config, to_json, to_plain, to_yaml
def test_dot_access_and_box_dots():
cfg = load_config()
assert cfg.service.port == 8080
assert cfg["db.port"] == 5432
assert type(to_plain(cfg)["db"]) is dict
def test_overrides_deep_merge():
cfg = load_config({"db": {"port": 6000}, "service": {"debug": True}})
assert cfg.db.port == 6000
assert cfg.db.host == "localhost"
assert cfg.service.debug is True
def test_missing_key_autovivifies():
cfg = load_config()
assert cfg.service.timeout is None
assert "timeout" in to_plain(cfg)["service"]
def test_frozen_rejects_mutation():
cfg = load_config(frozen=True)
assert cfg.service.port == 8080
with pytest.raises(BoxError):
cfg.service.port = 9999
assert isinstance(cfg.features, tuple)
with pytest.raises((AttributeError, TypeError)):
cfg.features.append("tracing")
def test_yaml_and_json_roundtrip():
cfg = load_config({"db": {"port": 6000}})
assert from_yaml(to_yaml(cfg)) == cfg
assert from_json(to_json(cfg)) == cfg
assert isinstance(from_json(to_json(cfg)).db, Box)
def test_frozen_box_dumps_unsafe_yaml():
frozen = load_config(frozen=True)
assert "!!python/tuple" in frozen.to_yaml()
with pytest.raises(yaml.YAMLError):
from_yaml(frozen.to_yaml())
assert from_yaml(to_yaml(frozen)) == load_config()
[pytest] pythonpath = .
Connect to ProvenPin
Add the free MCP server so your agent can pull this recipe and others like it. Same setup as the docs.
claude mcp add --transport http provenpin https://mcp.provenpin.com/mcp
{ "mcpServers": { "provenpin": { "url": "https://mcp.provenpin.com/mcp" } } }{ "servers": { "provenpin": { "type": "http", "url": "https://mcp.provenpin.com/mcp" } } }{ "mcpServers": { "provenpin": { "serverUrl": "https://mcp.provenpin.com/mcp" } } }{ "mcpServers": { "provenpin": { "type": "streamableHttp", "url": "https://mcp.provenpin.com/mcp" } } }Any other MCP client: Streamable HTTP at https://mcp.provenpin.com/mcp. No API key, no signup.
Related stacks
pydantic-settings v2 config from env, YAML and defaults with SecretStr
Nested pydantic-settings models loaded with precedence init > env > YAML > defaults, with env_nested_delimiter, SecretStr masking, and offline tests using tmp_path and monkeypatch.
PyYAML config validated with jsonschema Draft 2020-12
Load a YAML config with PyYAML safe loading and validate it offline against a JSON Schema Draft 2020-12 with jsonschema, including format checks and duplicate-key detection.