Skip to content

Core Concepts

The _target_ Key

The _target_ key maps a config block to a registered Python class.

Root config file: The root configuration file must have a _target_ field:

_target_: my_model  # Required at root level
learning_rate: 0.001

Nested configs: For nested configuration blocks, _target_ is optional when the parent class has a type hint pointing to a concrete, registered class. See Target Resolution for details on when _target_ can be omitted.

ConfigStore

ConfigStore is the central registry that implements target mappings - the association between string identifiers and Python classes. When you register a target:

rc.register(name="my_model", target=MyModel)
rc.register(name="my_dataset", target=MyDataset)

The registered names ("my_model", "my_dataset") are exactly the values you use for _target_ in your config files:

_target_: my_model    # Maps to MyModel class
hidden_size: 256

This decoupling allows config files to reference classes by stable string identifiers, independent of Python module paths or class renaming.

Viewing registered targets:

refs = rc.known_targets()
for name, ref in refs.items():
    print(f"{name}: {ref.target_class}")

Reserved Keys

ReausoConfig reserves the following keys (prefixed and suffixed with _) for framework use during composition and instantiation. These keys are consumed by the framework and cannot be used as field names in your configuration classes.

Key Purpose
_target_ Maps config block to a registered Python class
_ref_ References another config file for composition
_instance_ Shares an instantiated object across config paths
_lazy_ Marks a nested config for lazy instantiation
_required_ Marks a value as required (must be overridden)
_extend_ Appends items to a list during deep merge
_prepend_ Prepends items to a list during deep merge

These keys are stripped from the config before instantiation and are not passed to your class constructors. If you use a reserved key as a field name in your class, that field will never receive a value from config.

Validation

Before instantiation, configs are validated for:

  • Required fields (parameters without defaults)
  • Type compatibility
  • Target existence in registry

Resolution Pipeline

When you call rc.instantiate(), the following steps execute in order:

1. LOAD        Parse the config file (YAML, JSON, or TOML)
2. COMPOSE     Resolve all _ref_ references and deep merge
3. OVERRIDE    Apply programmatic overrides, then CLI overrides (CLI wins)
4. INTERPOLATE Resolve all ${...} expressions
5. EXTRACT     If inner_path is specified, extract that section
6. VALIDATE    Check required values and type compatibility
7. INSTANTIATE Recursively create objects via registered constructors

Lifecycle hooks fire at specific points during this pipeline: CONFIG_LOADED runs after step 2, BEFORE_INSTANTIATE and AFTER_INSTANTIATE run per-object during step 7, and ON_ERROR runs if any step raises an exception.