omry / omegaconf

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

fix: Nested structured config validation #1133

Open bzczb opened 11 months ago

bzczb commented 11 months ago

Motivation

This fixes the case where, in your schema, you have a structured config nested in multiple levels of Dict and List, such as Dict[Dict[str, User]], and the types don't get propagated correctly. This causes no validation to be done on the inner object. Also, after to_container(..., SCMode.INSTANTIATE), what should have been User in the result will show up as a dict.

Further explanation

Looking at the original issue case...

>>> typed.single_nest.level_1._metadata
ContainerMetadata(ref_type=<class '__main__.DeeplyNestedConf'>, object_type=<class '__main__.DeeplyNestedConf'>, optional=False, key='level_1', flags={}, flags_root=False, resolver_cache=defaultdict(<class 'dict'>, {}), key_type=typing.Any, element_type=typing.Any)

>>> typed.double_nest.level_1.nested_level_1._metadata
ContainerMetadata(ref_type=<class '__main__.DeeplyNestedConf'>, object_type=<class 'dict'>, optional=False, key='nested_level_1', flags={}, flags_root=False, resolver_cache=defaultdict(<class 'dict'>, {}), key_type=typing.Any, element_type=typing.Any)

The ref_type was getting propagated correctly, but the object_type was not.

Test Plan

Added test_merge_with_deep_nesting() which checks for the buggy behavior on various deeply-nested containers.

With these changes, there is a bit of coverage missing for basecontainer.py L982-L986. I don't know how to get that last bit of coverage...

Fixes

Fixes #1019 Nested structured config validation