omegaconf icon indicating copy to clipboard operation
omegaconf copied to clipboard

`unsafe_merge` crashes with nested structured config and union type

Open function2-llx opened this issue 1 year ago • 1 comments

Describe the bug unsafe_merge crashes with nested structured config and union type.

To Reproduce

from dataclasses import dataclass

from omegaconf import OmegaConf

@dataclass
class A:
    x: int | str

@dataclass
class B:
    a: A

def main():
    x = OmegaConf.unsafe_merge(OmegaConf.structured(B), {'a': {'x': 1}})
    print(x)

if __name__ == '__main__':
    main()

Expected behavior {'a': {'x': 1}} will be printed, just like OmegaConf.merge.

Actual result

Traceback (most recent call last):
  File "./test.py", line 18, in <module>
    main()
  File "./test.py", line 14, in main
    x = OmegaConf.unsafe_merge(OmegaConf.structured(B), {'a': {'x': 1}})
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../omegaconf/omegaconf.py", line 308, in unsafe_merge
    target.merge_with(*configs[1:])
  File ".../omegaconf/basecontainer.py", line 492, in merge_with
    self._format_and_raise(key=None, value=None, cause=e)
  File ".../omegaconf/base.py", line 231, in _format_and_raise
    format_and_raise(
  File ".../omegaconf/basecontainer.py", line 490, in merge_with
    self._merge_with(*others)
  File ".../omegaconf/basecontainer.py", line 514, in _merge_with
    BaseContainer._map_merge(self, other)
  File ".../omegaconf/basecontainer.py", line 399, in _map_merge
    dest_node._merge_with(src_node)
  File ".../omegaconf/basecontainer.py", line 514, in _merge_with
    BaseContainer._map_merge(self, other)
  File ".../omegaconf/basecontainer.py", line 358, in _map_merge
    expand(dest)
  File ".../omegaconf/basecontainer.py", line 342, in expand
    node._set_value(val)
  File ".../omegaconf/dictconfig.py", line 647, in _set_value
    raise e
  File ".../omegaconf/dictconfig.py", line 644, in _set_value
    self._set_value_impl(value, flags)
  File ".../omegaconf/dictconfig.py", line 677, in _set_value_impl
    self.__setitem__(k, v)
  File ".../omegaconf/dictconfig.py", line 314, in __setitem__
    self._format_and_raise(key=key, value=value, cause=e)
  File ".../omegaconf/base.py", line 231, in _format_and_raise
    format_and_raise(
  File ".../omegaconf/dictconfig.py", line 308, in __setitem__
    self.__set_impl(key=key, value=value)
  File ".../omegaconf/dictconfig.py", line 318, in __set_impl
    self._set_item_impl(key, value)
  File ".../omegaconf/basecontainer.py", line 535, in _set_item_impl
    if self._get_root() is value._get_root():
                           ^^^^^^^^^^^^^^^^^
  File ".../omegaconf/base.py", line 289, in _get_root
    assert isinstance(self, Container)
AssertionError

Additional context

  • [x] OmegaConf version: 2.3.0
  • [x] Python version: 3.11.4
  • [x] Operating system: Ubuntu 22.04

function2-llx avatar Jun 11 '23 08:06 function2-llx