hydra_zen.make_config#

hydra_zen.make_config(*fields_as_args, hydra_recursive=None, hydra_convert=None, hydra_defaults=None, zen_dataclass=None, bases=(), zen_convert=None, **fields_as_kwargs)[source]#

Returns a config with user-defined field names and, optionally, associated default values and/or type annotations.

Unlike builds, make_config is not used to configure a particular target object; rather, it can be used to create more general configs [1].

Parameters:
*fields_as_argsstr | ZenField

The names of the fields to be be included in the config. Or, ZenField instances, each of which details the name and their default value and/or the type annotation of a given field.

**fields_as_kwargsSupportedPrimitive | ZenField

Like fields_as_args, but field-name/default-value pairs are specified as keyword arguments. ZenField can also be used here to express a field’s type-annotation and/or its default value.

Named parameters of the forms hydra_xx, zen_xx, and _zen_xx are reserved to ensure future-compatibility, and cannot be specified by the user.

zen_convertOptional[ZenConvert]

A dictionary that modifies hydra-zen’s value and type conversion behavior. Consists of the following optional key-value pairs (hydra_zen.typing.ZenConvert):

  • dataclassbool (default=False):

    If True any dataclass type/instance without a _target_ field is automatically converted to a targeted config that will instantiate to that type/instance. Otherwise the dataclass type/instance will be passed through as-is.

basesTuple[Type[DataClass], …], optional (default=())

Base classes that the resulting config class will inherit from.

hydra_recursiveOptional[bool], optional (default=True)

If True, then Hydra will recursively instantiate all other hydra-config objects nested within this dataclass [2].

If None, the _recursive_ attribute is not set on the resulting config.

hydra_convertOptional[Literal[“none”, “partial”, “all”, “object”]], optional (default=”none”)

Determines how Hydra handles the non-primitive objects passed to configuration [3].

  • "none": Passed objects are DictConfig and ListConfig, default

  • "partial": Passed objects are converted to dict and list, with the exception of Structured Configs (and their fields).

  • "all": Passed objects are dicts, lists and primitives without a trace of OmegaConf containers

  • "object": Passed objects are converted to dict and list. Structured Configs are converted to instances of the backing dataclass / attr class.

If None, the _convert_ attribute is not set on the resulting config.

hydra_defaultsNone | list[str | dict[str, str | list[str] | None ]], optional (default = None)

A list in an input config that instructs Hydra how to build the output config [7] [8]. Each input config can have a Defaults List as a top level element. The Defaults List itself is not a part of output config.

zen_dataclassOptional[DataclassOptions]

A dictionary can specify any option that is supported by dataclasses.make_dataclass() other than fields.

Additionally, a 'module': <str> entry can be specified to enable pickle compatibility. See hydra_zen.typing.DataclassOptions for details.

frozenbool, optional (default=False)

Deprecated since version 0.9.0: frozen will be removed in hydra-zen 0.10.0. It is replaced by zen_dataclass={'frozen': <bool>}.

If True, the resulting config class will produce ‘frozen’ (i.e. immutable) instances. I.e. setting/deleting an attribute of an instance of the config will raise dataclasses.FrozenInstanceError at runtime.

config_namestr, optional (default=”Config”)

Deprecated since version 0.9.0: config_name will be removed in hydra-zen 0.10.0. It is replaced by zen_dataclass={'cls_name': <str>}.

The class name of the resulting config class.

Returns:
ConfigType[DataClass]

The resulting config class; a dataclass that possess the user-specified fields.

Raises:
hydra_zen.errors.HydraZenUnsupportedPrimitiveError

The provided configured value cannot be serialized by Hydra, nor does hydra-zen provide specialized support for it. See Configuration-Value Types Supported by Hydra and hydra-zen for more details.

See also

builds

Create a targeted structured config designed to “build” a particular object.

just

Create a config that “just” returns a class-object or function, without instantiating/calling it.

Notes

The resulting “config” is a dataclass-object [4] with Hydra-specific attributes attached to it, along with the attributes specified via fields_as_args and fields_as_kwargs. Unlike std-lib dataclasses, the default value for unsafe_hash is True.

Any field specified without a type-annotation is automatically annotated with typing.Any. Hydra only supports a narrow subset of types [5]; make_config will automatically ‘broaden’ any user-specified annotations so that they are compatible with Hydra.

make_config will automatically manipulate certain types of default values to ensure that they can be utilized in the resulting config and by Hydra:

  • Mutable default values will automatically be packaged in a default factory function [6]

  • A default value that is a class-object or function-object will automatically be wrapped by just, to ensure that the resulting config is serializable by Hydra.

For finer-grain control over how type annotations and default values are managed, consider using dataclasses.make_dataclass().

For details of the annotation SupportedPrimitive, see Configuration-Value Types Supported by Hydra and hydra-zen.

References

Examples

>>> from hydra_zen import make_config, to_yaml
>>> def pp(x):
...     return print(to_yaml(x))  # pretty-print config as yaml

Basic Usage

Let’s create a bare-bones config with two fields, named ‘a’ and ‘b’.

>>> Conf1 = make_config("a", "b")  # sig: `Conf(a: Any, b: Any)`
>>> pp(Conf1)
a: ???
b: ???

Now we’ll configure these fields with particular values:

>>> conf1 = Conf1(1, "hi")
>>> pp(conf1)
a: 1
b: hi
>>> conf1.a
1
>>> conf1.b
'hi'

We can also specify fields via keyword args; this is especially convenient for providing associated default values.

>>> Conf2 = make_config("unit", data=[-10, -20])
>>> pp(Conf2)
unit: ???
data:
- -10
- -20

Configurations can be nested

>>> Conf3 = make_config(c1=Conf1(a=1, b=2), c2=Conf2)
>>> pp(Conf3)
c1:
  a: 1
  b: 2
c2:
  unit: ???
  data:
  - -10
  - -20
>>> Conf3().c1.a
1

Configurations can be composed via inheritance

>>> ConfInherit = make_config(c=2, bases=(Conf2, Conf1))
>>> pp(ConfInherit)
a: ???
b: ???
unit: ???
data:
- -10
- -20
c: 2
>>> issubclass(ConfInherit, Conf1) and issubclass(ConfInherit, Conf2)  # type: ignore
True

Support for Additional Types

Types like complex and pathlib.Path are automatically supported by hydra-zen.

>>> ConfWithComplex = make_config(a=1+2j)
>>> pp(ConfWithComplex)
a:
  real: 1.0
  imag: 2.0
  _target_: builtins.complex

See Auto-Config Support for Additional Types via hydra-zen for a complete list of supported types.

Using ZenField to Provide Type Information

The ZenField class can be used to include a type-annotation in association with a field.

>>> from hydra_zen import ZenField as zf
>>> ProfileConf = make_config(username=zf(str), age=zf(int))
>>> # signature: ProfileConf(username: str, age: int)

Providing type annotations is optional, but doing so enables Hydra to perform checks at runtime to ensure that a configured value matches its associated type [4].

>>> pp(ProfileConf(username="piro", age=False))  # age should be an integer
<ValidationError: Value 'False' could not be converted to Integer>

These default values can be provided alongside type annotations

>>> C = make_config(age=zf(int, 0))  # signature: C(age: int = 0)

ZenField can also be used to specify fields_as_args; here, field names must be specified as well.

>>> C2 = make_config(zf(name="username", hint=str), age=zf(int, 0))
>>> # signature: C2(username: str, age: int = 0)

See Runtime Data Validation for more general data validation capabilities via hydra-zen.