-
Notifications
You must be signed in to change notification settings - Fork 131
Description
Describe the bug
If I merge two configs with the same schema but where one has a missing value that another entry uses for interpolation, the default dataclass for that variable type is used instead. This is dangerous since using the default is definitely not intended!
For instance, my use case merging resolved and unresolved configs to give a config which is "as resolved as possible"
To Reproduce
import copy
from omegaconf import OmegaConf
from dataclasses import *
import omegaconf
print(omegaconf.__version__)
@dataclass(unsafe_hash=True)
class WithDefaults:
x: int = 0
y: int = 0
@dataclass(unsafe_hash=True)
class B:
b: WithDefaults = '${a}' # this value relies on `a` in the top level
@dataclass(unsafe_hash=True)
class Parent:
a: str = '???' # deliberately leave missing
b: B = B()
cfg = OmegaConf.structured(Parent())
cfg2 = OmegaConf.structured(Parent(b='???'))
cfg.merge_with(cfg2)
print(cfg)
Output:
2.3.0
{'a': '???', 'b': {'b': {'x': 0, 'y': 0}}}
Expected behavior
cfg2 should not have the default B
it should remain unresolved since I'm merging with a a config that contains ???
.
A merge of '${interpolation}' <- '???'
should result in '${interpolation}' not the default dataclass.
In a merge, MISSING must not be preferred and certainly a default dataclass should not be preferred
Output should read: {'a': '???', 'b': {'b': '${a}'}}
Additional context
- OmegaConf version: 2.3.0
- Python version: 3.11.10
- Operating system: Mac OS 14.6 (23G80)
- Please provide a minimal repro
The undesired behaviour seems to occur in expand
function that is inside BaseContainer._map_merge: val = rt
.