OmegaConf 2.1.0
2.1.0 (2021-06-07)
OmegaConf 2.1 is a major release introducing substantial new features, and introducing some incompatible changes.
The biggest area of improvement in 2.1 is interpolations and resolvers. In addition - OmegaConf containers are now
much more compatible with their plain Python container counterparts (dict and list).
Features
API Enhancements
- OmegaConf.select() now takes an optional default value to return if a key is not found (#228)
- flag_override can now override multiple flags at the same time (#400)
- Add the OmegaConf.to_object method, which converts Structured Configs to native instances of the underlying
@dataclass
or@attr.s
class. (#472) - Add OmegaConf.unsafe_merge(), a fast merge variant that destroys the input configs (#482)
- New function
OmegaConf.has_resolver()
allows checking whether a resolver has already been registered. (#608) - Adds OmegaConf.resolve(cfg) for in-place interpolation resolution on cfg (#640)
- force_add flag added to OmegaConf.update(), ensuring that the path is created even if it will result in insertion of new values into struct nodes. (#664)
- Add DictConfig support for keys of type int, float and bool (#149), (#483)
- Structured Configs fields without a value are now automatically treated as
OmegaConf.MISSING
(#390) - Add minimal support for typing.TypedDict (#473)
- OmegaConf.to_container now takes a
structured_config_mode
keyword argument. Settingstructured_config_mode=SCMode.DICT_CONFIG
causesto_container
to not convert Structured Config objects to python dicts (it leaves them as DictConfig objects). (#548)
Interpolation and resolvers
- Support for relative interpolation (#48)
- Add ability to nest interpolations, e.g. ${foo.${bar}}}, ${oc.env:{$var1},${var2}}, or ${${func}:x1,x2} (#445)
- Custom resolvers can now access the parent and the root config nodes (#266)
- For
OmegaConf.{update, select}
and in interpolations, bracketed keys may be used as an alternative form to dot notation,
e.g. foo.1 is equivalent to foo[1], [foo].1 and [foo][1]. (#179) - Custom resolvers may take non string arguments as input, and control whether to use the cache. (#445)
- Dots may now be used in resolver names to denote namespaces (e.g:
${namespace.my_func:123}
) (#539) - New resolver
oc.select
, enabling node selection with a default value to use if the node cannot be selected (#541) - New resolver
oc.decode
that can be used to automatically convert a string to bool, int, float, dict, list, etc. (#574) - New resolvers
oc.dict.keys
andoc.dict.values
provide a list view of the keys or values of a DictConfig node. (#643) - New resolver
oc.create
can be used to dynamically generate config nodes (#645) - New resolver
oc.deprecated
, that enables deprecating config nodes (#681) - The dollar character
$
is now allowed in interpolated key names, e.g.${$var}
(#600)
Misc
- New PyDev.Debugger resolver plugin for easier debugging in PyCharm and VSCode (#214)
- OmegaConf now supports Python 3.9 (#447)
- Support for Python 3.10 postponed annotation evaluation (#303)
- Experimental support for enabling objects in config via "allow_objects" flag (#382)
Bug Fixes
ListConfig.append()
now copies input config nodes (#601)- Fix loading of OmegaConf 2.0 pickled configs (#718)
- Fix support for forward declarations in Dict and Lists (#378)
- Fix bug that allowed instances of Structured Configs to be assigned to DictConfig with different element type. (#386)
- Fix exception raised when checking for the existence of a key with an incompatible type in DictConfig (#394)
- Fix loading of an empty file via a file-pointer to return an empty dictionary (#403)
- Fix pickling of Structured Configs with fields annotated as Dict[KT, VT] or List[T] on Python 3.6. (#407)
- Assigning a primitive type to a Subscripted Dict now raises a descriptive message. (#409)
- Fix assignment of an invalid value to a DictConfig to raise an exception without modifying the config object (#409)
- Assigning a Structured Config to a Dict annotation now raises a descriptive error message. (#410)
- OmegaConf.to_container() raises a ValueError on invalid input (#418)
- Fix ConfigKeyError in some cases when merging lists containing interpolation values (#422)
- DictConfig.get() in struct mode return None like standard Dict for non-existing keys (#425)
- Fix bug where interpolations were unnecessarily resolved during merge (#431)
- Fix bug where assignment of an invalid value to a ListConfig raised an exception but left the object modified. (#433)
- When initializing a Structured Config with an incorrectly-typed value, the resulting ValidationError now properly reports the offending value in its error message. (#435)
- Fix assignment of a Container to itself causing it to clear its content (#449)
- Fix bug where DictConfig's shallow copy didn't work properly in some cases. (#450)
- Fix support for merge tags in YAML files (#470)
- Fix merge into a custom resolver node that raises an exception (#486)
- Fix merge when element type is a Structured Config (#496)
- Fix ValidationError when setting to None an optional field currently interpolated to a non-optional one (#524)
- Fix OmegaConf.to_yaml(cfg) when keys are of Enum type (#531)
- When a DictConfig has enum-typed keys,
__delitem__
can now be called with a string naming the enum member to be deleted. (#554) OmegaConf.select()
of a missing (???
) node from a ListConfig withthrow_on_missing
set to True now raises the intended exception. (#563)DictConfig.{get(),pop()}
now returnNone
when the accessed key evaluates toNone
, instead of the specified default value (for consistency with regular Python dictionaries). (#583)ListConfig.get()
now returnNone
when the accessed key evaluates toNone
, instead of the specified default value (for consistency with DictConfig). (#583)- Fix creation of structured config from a dict subclass: data from the dict is no longer thrown away. (#584)
- Assignment of a dict/list to an existing node in a parent in struct mode no longer raises ValidationError (#586)
- Nested flag_override now properly restore the original state (#589)
- Fix OmegaConf.create() to set the provided
parent
when creating a config from a YAML string. (#648) - OmegaConf.select now returns None when attempting to select a child of a value or None node (#678)
- Improve error message when creating a config from a Structured Config that fails type validation (#697)
API changes and deprecations
- DictConfig
__getattr__
access, e.g.cfg.foo
, is now raising a AttributeError if the key "foo" does not exist (#515) - DictConfig
__getitem__
access, e.g.cfg["foo"]
, is now raising a KeyError if the key "foo" does not exist (#515) - DictConfig get access, e.g.
cfg.get("foo")
, now returnsNone
if the key "foo" does not exist (#527) -
Omegaconf.select(cfg, key, default, throw_on_missing)
now requires keyword arguments for everything afterkey
(#228) - Structured Configs with nested Structured config field that does not specify a default value are now interpreted as MISSING (
???
) instead of auto-expanding (#411) - OmegaConf.update() is now merging dict/list values into the destination node by default. Call with merge=False to replace instead. (#667)
-
register_resolver()
is deprecated in favor ofregister_new_resolver()
, allowing resolvers to (i) take non-string arguments like int, float, dict, interpolations, etc. and (ii) control the cache behavior (now disabled by default) (#426) - Merging a MISSING value onto an existing value no longer changes the target value to MISSING. (#462)
- When resolving an interpolation of a config value with a primitive type, the interpolated value is validated and possibly converted based on the node's type. (#488)
- DictConfig and ListConfig shallow copy is now performing a deepcopy (#492)
-
OmegaConf.select()
,DictConfig.{get(),pop()}
,ListConfig.{get(),pop()}
no longer return the specified default value when the accessed key is an interpolation that cannot be resolved: instead, an exception is raised. (#543) - OmegaConf.{merge, unsafe_merge, to_yaml} now raises a ValueError when called on a str input. Previously an AssertionError was raised. (#560)
- All exceptions raised during the resolution of an interpolation are either
InterpolationResolutionError
or a subclass of it. (#561) -
key in cfg
now returns True whenkey
is an interpolation even if the interpolation target is a missing ("???") value. (#562) -
OmegaConf.select()
as well as container methodsget()
andpop()
do not return their default value anymore when the accessed key is an interpolation that cannot be resolved: instead, an exception is raised. (#565) - Implicitly empty resolver arguments (e.g.,
${foo:a,}
) are deprecated in favor of explicit quoted strings (e.g.,${foo:a,""}
) (#572) - The
env
resolver is deprecated in favor ofoc.env
, which keeps the string representation of environment variables, does not cache the resulting value, and handles "null" as default value. (#573) -
OmegaConf.get_resolver()
is deprecated: use the newOmegaConf.has_resolver()
to check for the existence of a resolver. (#608) - Interpolation cycles are now forbidden and will trigger an InterpolationResolutionError on access. (#662)
- Support for Structured Configs that subclass
typing.Dict
is now deprecated. (#663) - Remove BaseContainer.{pretty,select,update_node} that have been deprecated since OmegaConf 2.0. (#671)