API Reference#

Core Classes#

ConfigBase#

The main configuration class that provides inheritance, type validation, and serialization capabilities.

class zencfg.ConfigBase(**kwargs)[source]#

Bases: object

Base class for all config objects, instanciates a new ConfigBase object.

Class creation We manually enable inheritance of class-level attributes (see notes for detail). You can specify which configuration (sub)-class you actually want to create by passing a “_config_name” key in kwargs. The subclass with that _config_name will be instantiated instead of the BaseConfig.

Class hierarchy Each direct descendent from ConfigBase will have a _registry attribute and track their children. In other words, for each main configuration category, create one subclass. Each config instance in this category should inherit from that subclass.

Notes

Note that by default, attributes are not inherited since they are class-level attributes, not actual constructor parameters. By default, Python does not automatically copy class attributes into instance attributes at __init__ time.

To fix this, we manually collect the defaults:

  • gather_defaults(cls):
    • walk the entire Method Resolution Order (MRO), from the root (object) up to the child class, collecting all fields that are not private or callable.

    • Because we do for base in reversed(cls.__mro__):, we effectively start from the oldest parent (like Checkpoint) and end at the child (CheckpointSubclass), so the child can override any fields if it redefines them.

  • __init__:
    • We call gather_defaults(type(self)) to get all inherited fields.

    • Check for any missing required fields (not in defaults).

    • Assign defaults to self.

    • Then override with any passed-in kwargs, including name.

instantiate() Any[source]#

Instantiate the target class with config parameters.

This method creates an instance of the class specified in _target_class using the configuration parameters as constructor arguments.

Only the current config is instantiated - nested ConfigBase objects are passed as-is (not recursively instantiated).

Returns:

An instance of the target class

Return type:

Any

Raises:
  • NotImplementedError – If _target_class is not set and this method is not overridden

  • ImportError – If the target class cannot be imported

  • TypeError – If the target class cannot be instantiated with the given parameters

Examples

You can specify the target class as a class directly or as a string:

>>> class LinearConfig(ConfigBase):
...     _target_class = "torch.nn.Linear"
...     in_features: int = 784
...     out_features: int = 10
>>> config = LinearConfig()
>>> model = config.instantiate()  # Creates torch.nn.Linear(in_features=784, out_features=10)

Alternatively, you can customize the instantiate method:

>>> class CustomConfig(ConfigBase):
...     param1: int = 42
...     def instantiate(self):
...         return MyCustomClass(self.param1)
>>> config = CustomConfig()
>>> obj = config.instantiate()
to_dict(flatten: bool = False, parent_key: str = '') Dict[str, Any][source]#

Returns a dictionary representation of this config (either nested or flattened).

Bunch#

A dictionary-like object that exposes its keys as attributes, with special handling for nested updates. This is what we return when we use the config.to_dict() method.

class zencfg.bunch.Bunch(init={})[source]#

Bases: dict

A dict exposing its keys as attributes

Warning

We override the default update function. The new one updates each nested dict individually. This may be a surprising behaviour.

Notes

  • At init, we explicitly go through each key, value pair to make sure that a nested dict becomes a nested Bunch.

  • We override the update to make sure that a nested Bunch is updated correctly. This may be a surprising behaviour.

Examples

>>> test = {'a': {'b': 3, 'c': 4}, 'd': 5}
>>> bunch = Bunch(test)

# Check what happens if we update an element with another dict: >>> bunch.update(dict(a=dict(b=5))) {‘a’: {‘b’: 5, ‘c’: 4}, ‘d’: 5}

# Compare this with what happens if we update a regular dict: >>> test.update(dict(a=dict(b=5))) {‘a’: {‘b’: 5}, ‘d’: 5}

update([E, ]**F) None.  Update D from mapping/iterable E and F.[source]#

If E is present and has a .keys() method, then does: for k in E.keys(): D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]

Loading and Instantiating Configurations#

make_config#

Create a config instance from any source: - ConfigBase class: instantiate with optional overrides - ConfigBase instance: apply overrides to a copy of instance - File path (str or Path): load a configuration class or instance from a file

zencfg.make_config(source: Type[ConfigBase] | ConfigBase | str | Path, name: str | None = None, /, **overrides) ConfigBase[source]#

Create a config instance from any source with overrides.

Parameters:
  • source (Union[Type[ConfigBase], ConfigBase, str, Path]) – Source to create config from: - ConfigBase class: instantiate with overrides - ConfigBase instance: apply overrides to copy - str/Path: file path to load config from

  • name (str, optional) – Required when source is a file path. Name of class/instance to load.

  • **overrides – Keyword arguments to override in the config

Returns:

Config instance with overrides applied

Return type:

ConfigBase

Examples

>>> # From class
>>> config = make_config(TrainingConfig, batch_size=32)
>>>
>>> # From file
>>> config = make_config("configs.py", "TrainingConfig", epochs=100)
>>> config = make_config(Path("configs.py"), "TrainingConfig", epochs=100)
>>>
>>> # From instance
>>> base = TrainingConfig()
>>> config = make_config(base, learning_rate=0.001)

make_config_from_cli#

Override any parameters of a configuration via the command-line argument. The configuration to load can be given as class, instance, or file.

zencfg.make_config_from_cli(source: Type[ConfigBase] | ConfigBase | str | Path, name: str | None = None, /, strict: bool = False) ConfigBase[source]#

Create a config instance with command-line argument overrides.

Parameters:
  • source (Union[Type[ConfigBase], ConfigBase, str, Path]) – Source to create config from (class, instance, or file path)

  • name (str, optional) – Required when source is a file path. Name of class/instance to load.

  • strict (bool, default=False) – If True, raises errors on type conversion failures

Returns:

Config instance with command-line overrides applied

Return type:

ConfigBase

Examples

>>> # From class
>>> config = make_config_from_cli(TrainingConfig)
>>>
>>> # From file
>>> config = make_config_from_cli("configs.py", "TrainingConfig")
>>> config = make_config_from_cli(Path("configs.py"), "TrainingConfig")

make_config_from_flat_dict#

Create a configuration instance from a flat dictionary (with dot notation to signify nested keys).

zencfg.make_config_from_flat_dict(config_cls: Any, flat_dict: Dict[str, Any], strict: bool = False) Any[source]#

Instantiates a config class from a flat dictionary.

Parameters:
  • config_cls (ConfigBase) – The config class to instantiate.

  • flat_dict (Dict[str, Any]) – “Flat” dict of the form {“key1”: value1, “key2”: value2, “key1.subkey”: “value”, …} It’s a single level dict (no nesting). Instead, the keys are nested using dots.

  • strict (bool) – If True, raise a TypeError on parsing errors. Otherwise, log a warning.

Returns:

An instance of ‘config_cls’ with values from ‘flat_dict’ with the loaded values.

Return type:

ConfigBase

make_config_from_nested_dict#

Create a configuration instance from a nested dictionary structure.

zencfg.make_config_from_nested_dict(config_cls: Any, nested_dict: Dict[str, Any], strict: bool, path: str = '') Any[source]#

Build a config instance from a nested dictionary with inheritance support.

Creates an instance of config_cls (or its appropriate subclass) using values from nested_dict. Handles nested ConfigBase fields recursively.

For ConfigBase fields, values are resolved with the following precedence: 1. Class defaults (from parent and child classes) 2. _config_name (preserved from default instance if not overridden) 3. User-provided values

Parameters:
  • config_cls (type) – The config class to instantiate (must be a ConfigBase subclass for inheritance)

  • nested_dict (dict) – Nested dictionary of values. For ConfigBase fields, can contain either: - str: treated as _config_name to select subclass (e.g. {config_cls: CLASS_NAME_STR}) - dict: values to override in the instance (e.g. {config_cls: {param1: value1, param2: value2}})

  • strict (bool) – If True, raises on type conversion errors and missing required fields. If False, keeps original values and sets missing fields to None.

  • path (str, optional) – Current path in the config hierarchy, used for error messages.

Return type:

Instance of config_cls (or selected subclass) with applied values

Raises:
  • TypeError – If invalid value type provided for a ConfigBase field

  • ValueError – If unknown config keys or missing required fields (in strict mode)

load_config_from_file#

Load a configuration class or instance from a Python file.

zencfg.load_config_from_file(file_path: str | Path, config_name: str) Type[ConfigBase] | ConfigBase[source]#

Load a config class or instance from a file.

Deprecated Functions#

Warning

The following functions are deprecated and will be removed in a future version.

cfg_from_commandline#

Deprecated since version 1.0.0: Use make_config_from_cli() instead.

Parse command-line arguments and create a configuration instance.

zencfg.cfg_from_commandline(config_class: Type[ConfigBase], strict: bool = False) ConfigBase[source]#

Takes a Config class and returns an instance of it, with values updated from command line.

Deprecated since version 1.0.0: Use make_config_from_cli() instead.