Skip to content

Hydra utils

Utility functions related to working with Hydra.

patched_safe_name #

patched_safe_name(obj: Any, repr_allowed: bool = True)

Patches a bug in Hydra-zen where the target of inner classes is incorrect: https://github.com/mit-ll-responsible-ai/hydra-zen/issues/705

interpolate_config_attribute #

interpolate_config_attribute(
    *attributes: str,
    default: Any | Literal[MISSING] = MISSING
)

Use this in a config to to get an attribute from another config after it is instantiated.

Multiple attributes can be specified, which will lead to trying each of them in order until the attribute is found. If none are found, then an error will be raised.

For example, if we only know the number of classes in the datamodule after it is instantiated, we can set this in the network config so it is created with the right number of output dims.

_target_: torchvision.models.resnet50
num_classes: ${instance_attr:datamodule.num_classes}

This is equivalent to:

import hydra_zen import torchvision.models resnet50_config = hydra_zen.builds( ... torchvision.models.resnet50, ... num_classes=interpolate_config_attribute("datamodule.num_classes"), ... populate_full_signature=True, ... ) print(hydra_zen.to_yaml(resnet50_config)) # doctest: +NORMALIZE_WHITESPACE target: torchvision.models.resnet.resnet50 weights: null progress: true num_classes: ${instance_attr:datamodule.num_classes}

interpolated_field #

interpolated_field(
    interpolation: str,
    default: T | Literal[MISSING] = MISSING,
    default_factory: (
        Callable[[], T] | Literal[MISSING]
    ) = MISSING,
    instance_attr: bool = False,
) -> T

Field with a default value computed with a OmegaConf-style interpolation when appropriate.

When the dataclass is created by Hydra / OmegaConf, the interpolation is used. Otherwise, behaves as usual (either using default or calling the default_factory).

Parameters#

interpolation: The string interpolation to use to get the default value. default: The default value to use when not in a hydra/OmegaConf context. default_factory: The default value to use when not in a hydra/OmegaConf context. instance_attr: Whether to use the instance_attr custom resolver to run the interpolation with respect to instantiated objects instead of their configs. Passing interpolation='${instance_attr:some_config.some_attr}' has the same effect.

This last parameter is important, since in order to retrieve the instance attribute, we need to instantiate the objects, which could be expensive. These instantiated objects are reused at least, but still, be mindful when using this parameter.

add_attributes #

add_attributes(fn: partial[T]) -> Partial[T]

Adds a getattr to the partial that returns the value in v.keywords.

get_attr #

get_attr(obj: Any, *attributes: str)

Recursive version of getattr when the attribute is like 'a.b.c'.

register_instance_attr_resolver #

register_instance_attr_resolver(
    instantiated_objects_cache: dict[str, Any]
) -> None

Registers the instance_attr custom resolver with OmegaConf.

resolve_dictconfig #

resolve_dictconfig(dict_config: DictConfig) -> Config

Resolve all interpolations in the DictConfig.

Returns a Config object, which is a simple dataclass used to give nicer type hints for the contents of an experiment config.

instance_attr #

instance_attr(
    *attributes: str,
    _instantiated_objects_cache: (
        MutableMapping[str, Any] | None
    ) = None
)

Allows interpolations of the instantiated objects attributes (rather than configs).

This is very hacky

This is quite hacky and very dependent on the code of Hydra / OmegaConf not changing too much in the future. For this reason, consider pinning the versions of these libraries in your project if you intend do use this feature.

This works during a call to hydra.utils.instantiate, by looking at the stack trace to find the instantiated objects, which are in a variable in that function.

If there is a ${instance_attr:datamodule.num_classes} interpolation in a config, this will:

  1. instantiate the datamodule config
  2. store it at the key 'datamodule' in the instantiated objects cache dict (if passed).

    (This is useful since it makes it possible for us to later reuse this instantiated datamodule instead of re-instantiating it.)

  3. Retrieve the value of the attribute (getattr(datamodule, 'num_classes')) and return it.

being_called_in_hydra_context #

being_called_in_hydra_context() -> bool

Returns True if this function is being called indirectly by Hydra/OmegaConf.

Can be used in a field default factory to change the default value based on whether the config is being instantiated by Hydra vs in code. For example, you could have a default value for a field a of a dataclass Foo that is 'a=123when called in code, for example when doingFoo()in a python file, but then when called by Hydra, the default value could bea=${some_interpolation}`, so that Hydra/OmegaConf resolve that interpolation.

make_config_and_store #

make_config_and_store(
    target: Callable[..., Target],
    *,
    store: ZenStore,
    **overrides
)

Creates a config dataclass for the given target and stores it in the config store.

This uses hydra_zen.builds to create the config dataclass and stores it at the name config_name, or target.__name__.