Config

Configuration container with temporary context manager for scoped changes

source

Config


def Config(
    args:VAR_POSITIONAL, kwargs:VAR_KEYWORD
):

Store of arbitrary values

Usage Examples

With dataclass

@dataclasses.dataclass
class _Dc(Config):
    a: int = 1
    b: str = '2'
    c: dict = dataclasses.field(default_factory=lambda: {'c1': 1})

t = _Dc()
print(t)

test_eq(t.a, 1)
with t(a=3): test_eq(t.a, 3)
test_eq(t.a, 1)

t.update(a=3, d=10)
test_eq(t.a, 3)
test_is(hasattr(t, 'd'), False)

t
_Dc(a=1, b='2', c={'c1': 1})
_Dc(a=3, b='2', c={'c1': 1})

With inheritance

Config supports inheritance for composing hierarchical configurations:

class _A(Config):
    a: int = 1
    b: str = '2'

class _B(_A):
    a: int = 7
    c: dict
    def __init__(self, *args, **kwargs): self.c = {'c1': 1}

b = _B()
print(b)

test_eq(b.a, 7)
with b(a=3): test_eq(b.a, 3)
test_eq(b.a, 7)

b.update(a=3, d=10)
test_eq(b.a, 3)
test_is(hasattr(b, 'd'), False)

b
{'a': 7, 'c': {'c1': 1}, 'b': '2'}
{'a': 3, 'c': {'c1': 1}, 'b': '2'}

Context manager patterns

# Temporary overrides for testing
class AppConfig(Config):
    debug: bool = False
    log_level: str = 'INFO'
    timeout: int = 30

cfg = AppConfig()

# Normal operation
test_eq(cfg.debug, False)

# Test with debug enabled
with cfg(debug=True, log_level='DEBUG'):
    test_eq(cfg.debug, True)
    test_eq(cfg.log_level, 'DEBUG')
    test_eq(cfg.timeout, 30)  # unchanged

# Reverted after context
test_eq(cfg.debug, False)
test_eq(cfg.log_level, 'INFO')