rbgirshick / yacs

YACS -- Yet Another Configuration System
Apache License 2.0
1.28k stars 90 forks source link

Allow type mismatch when one type is subclass of the other #45

Open ManifoldFR opened 4 years ago

ManifoldFR commented 4 years ago

This would allow doing the following thing:

class SpecialConfig(CfgNode):
    field1: int = 0
    field2: str = 'foo'

_C = CfgNode()
_C.special = SpecialConfig()

def update_spec_config(spec_config: SpecialConfig):
    config = _C.clone()
    new_config = CfgNode()
    new_config.special = spec_config

    print("Default config:\n\r", config)
    config.merge_from_other_cfg(new_config)
    return config

if __name__ == '__main__':
    spec = dict(field1=1, field2='bar')
    config = update_spec_config(SpecialConfig(spec))
    print("New config:")
    print(config)

At present, this won't work, yielding the error:

Traceback (most recent call last):
  File "yacs_config.py", line 23, in <module>
    config = update_spec_config(SpecialConfig(spec))
  File "yacs_config.py", line 18, in update_spec_config
    config.merge_from_other_cfg(new_config)
  File "/home/manifold/miniconda3/lib/python3.8/site-packages/yacs/config.py", line 217, in merge_from_other_cfg
    _merge_a_into_b(cfg_other, self, self, [])
  File "/home/manifold/miniconda3/lib/python3.8/site-packages/yacs/config.py", line 456, in _merge_a_into_b
    v = _check_and_coerce_cfg_value_type(v, b[k], k, full_key)
  File "/home/manifold/miniconda3/lib/python3.8/site-packages/yacs/config.py", line 510, in _check_and_coerce_cfg_value_type
    raise ValueError(
ValueError: Type mismatch (<class '__main__.SpecialConfig'> vs. <class 'yacs.config.CfgNode'>) with values ( vs. field1: 1
field2: bar) for config key: special

Wouldn't it make sense to allow this case, because SpecialConfig is a subclass of CfgNode? It's not obvious that this is useful, because I could do without the subclass. However having a class allows for typed access to values and a constructor with default values