Skip to content

OmegaConf 2.1.0.rc1

Pre-release
Pre-release
Compare
Choose a tag to compare
@omry omry released this 13 May 00:35
· 203 commits to master since this release
363e510

2.1.0.rc1 (2021-05-12)

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. Setting structured_config_mode=SCMode.DICT_CONFIG causes to_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 and oc.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

  • 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 with throw_on_missing set to True now raises the intended exception. (#563)
  • DictConfig.{get(),pop()} now return None when the accessed key evaluates to None, instead of the specified default value (for consistency with regular Python dictionaries). (#583)
  • ListConfig.get() now return None when the accessed key evaluates to None, 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 returns None if the key "foo" does not exist (#527)
  • Omegaconf.select(cfg, key, default, throw_on_missing) now requires keyword arguments for everything after key (#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 of register_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 when key is an interpolation even if the interpolation target is a missing ("???") value. (#562)
  • OmegaConf.select() as well as container methods get() and pop() 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 of oc.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 new OmegaConf.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)

Miscellaneous changes

  • Optimized config creation time. Up to 4x faster in benchmarks (#477)
  • ListConfig.__contains__ optimized, about 15x faster in a benchmark (#529)
  • Optimized ListConfig iteration by 12x in a benchmark (#532)