Advanced Usage

This tutorial covers additional features of LayeredConfigTree, including freezing, iteration, deletion, and error handling.

Freezing a Tree

Call freeze() to make a tree read-only. This recursively freezes all children:

from layered_config_tree import LayeredConfigTree

config = LayeredConfigTree({"database": {"host": "localhost", "port": 5432}})
config.freeze()

try:
    config.database.host = "new-host"
except Exception as e:
    print(type(e).__name__)
ConfigurationError

Freezing is useful to enforce that configuration is not accidentally modified after initialization.

Iterating Over Keys

LayeredConfigTree supports dictionary-style iteration:

config = LayeredConfigTree({"a": 1, "b": 2, "c": 3})

for key in config:
    print(key)
a
b
c

You can also use keys(), values(), and items():

print(list(config.keys()))
print(len(config))
['a', 'b', 'c']
3

Membership Testing

Use in to check whether a key exists:

print("a" in config)
print("missing" in config)
True
False

Deleting Keys

Keys can be removed using del:

del config["c"]
print(list(config.keys()))
['a', 'b']

Error Handling

The package provides a hierarchy of specific exceptions:

Since ConfigurationKeyError inherits from both ConfigurationError and KeyError, you can catch it with either:

tree = LayeredConfigTree({"a": 1})

try:
    tree["nonexistent"]
except KeyError:
    print("caught as KeyError")
caught as KeyError