omry / omegaconf

Flexible Python configuration system. The last one you will ever need.
BSD 3-Clause "New" or "Revised" License
1.94k stars 106 forks source link

Merging does not preserve target `ref_type` when source field type hint is a dict annotation #998

Open Jasha10 opened 2 years ago

Jasha10 commented 2 years ago

Describe the bug Merging does not preserve target ref_type when source field type hint is a dict annotation. This causes Hydra bug https://github.com/facebookresearch/hydra/issues/2348.

To Reproduce

# tmp.py
from dataclasses import dataclass, field
from enum import Enum
from typing import Any, Dict

from omegaconf import OmegaConf

class RunMode(Enum):
    RUN = 1

@dataclass
class HConf:
    mode: RunMode

@dataclass
class MyConf:
    hydra: Dict[str, Any]

cfg1 = OmegaConf.create({"hydra": HConf})
cfg2 = OmegaConf.create(MyConf)

cfg = OmegaConf.merge(cfg1, cfg2)
assert cfg.hydra._metadata.object_type == HConf
mode_ref_type = cfg.hydra._get_node("mode")._metadata.ref_type
assert mode_ref_type == RunMode, mode_ref_type
$ python tmp.py
Traceback (most recent call last):
  File "/home/rig1/dev/hydra/tmp.py", line 25, in <module>
    assert mode_ref_type == RunMode, mode_ref_type
AssertionError: typing.Any

Expected behavior Since the node cfg.hydra has a structured object_type (i.e. HConf), the field node cfg.hydra.mode should have ref type RunMode (in keeping with the type annotation on the HConf dataclass).

Additional context