omegaconf icon indicating copy to clipboard operation
omegaconf copied to clipboard

OmegaConf.update AssertionError on key pointing into None-valued DictConfig.

Open Jasha10 opened this issue 3 years ago • 3 comments

Describe the bug The OmegaConf.update method throws an AssertionError when the key argument passed to OmegaConf.update points inside of a DictConfig instance whose _content is None.

To Reproduce

from dataclasses import dataclass
from typing import Optional
from omegaconf import OmegaConf
from pytest import raises

@dataclass
class Child:
    x: int = 123
    y: int = 456

@dataclass
class Parent:
    child: Optional[Child] = None

cfg = OmegaConf.structured(Parent)

with raises(AssertionError, match="Unexpected type for root: NoneType"):
    OmegaConf.update(cfg=cfg, key="child.x", value=789)

Expected behavior I think OmegaConf should fail gracefully (or maybe not fail at all) in this situation rather than throwing an AssertionError.

Additional context

  • [X] OmegaConf version: 2.2.3
  • [X] Python version: 3.9.12
  • [X] Operating system: ubuntu 20.04
  • [X] Please provide a minimal repro

Edit:

Here is the full traceback:
$ OC_CAUSE=1 python repro2.py
Traceback (most recent call last):
  File "/home/homestar/dev/mrepo/pysc/repro2.py", line 17, in <module>
    OmegaConf.update(cfg=cfg, key="child.x", value=789)
  File "/home/homestar/miniconda3/envs/pysc/lib/python3.10/site-packages/omegaconf/omegaconf.py", line 709, in update
    assert isinstance(
AssertionError: Unexpected type for root: NoneType

Jasha10 avatar Nov 17 '22 21:11 Jasha10

OmegaConf.merge does not exhibit the same failure mode.

-- Click here for an example --
from dataclasses import dataclass
from typing import Optional
from omegaconf import OmegaConf

@dataclass
class Child:
    x: int = 123
    y: int = 456

@dataclass
class Parent:
    child: Optional[Child] = None

cfg = OmegaConf.structured(Parent)
other = {"child": {"x": 789}}
out = OmegaConf.merge(cfg, other)

assert OmegaConf.get_type(out.child) is Child
assert out == {"child": {"x": 789, "y": 456}}

I feel that OmegaConf.update's behavior should be consistent with that of OmegaConf.merge: calling update should result in a node out.child that is a non-None structured config backed the Child class.

Jasha10 avatar Nov 18 '22 11:11 Jasha10

I feel that OmegaConf.update's behavior should be consistent with that of OmegaConf.merge: calling update should result in a node out.child that is a non-None structured config backed the Child class.

Dunno, that would be an insert, not an update.

omry avatar Jan 19 '23 09:01 omry