omry / omegaconf

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

Feature Request: Key-based readonly flag. #1161

Open Daraan opened 8 months ago

Daraan commented 8 months ago

Is your feature request related to a problem? Please describe. My motivation underneath is to lock interpolations so that they cannot be overwritten. A general form would be to implement key-based read-only checks.

Describe the solution you'd like I could think of three solutions 2) is likely the easiest to implement, 1) while more limited is more straight forward, and 3) needs to build up on something first.

1) A readonly_interpolations flag on nodes. Maybe a bit more involved: If the flag is set check on write if the current value is an interpolation if so raise.

2) Or the more general and probably most simplest solution that adds a set to check to the flags.

def set_readonly_keys(conf, keys:
    conf._set_flag("readonly_keys", [keys])

# And checked at the same places:
# replace:
if self._get_flag("readonly"): raise ...` 
# with 
if self._get_flag("readonly") or key in self._get_flag("readonly_keys"): raise ...

Do you think 2) is a possible solution?

odelalleau commented 8 months ago

You can try using something like:

def set_readonly_keys(conf, keys):
    for key in keys:
        OmegaConf.set_readonly(conf._get_node(key), True)

Or to make all interpolations read-only automatically:

def set_readonly_interpolations(conf):
    if conf._is_interpolation():
        OmegaConf.set_readonly(conf, True)
    elif isinstance(conf, DictConfig):
        for key in conf:
            set_readonly_interpolations(conf._get_node(key))
    elif isinstance(conf, ListConfig):
        for key in range(len(conf)):
            set_readonly_interpolations(conf._get_node(key))

Unfortunately this requires accessing some internal API, maybe OmegaConf should expose some public API to make it more convenient.

Daraan commented 8 months ago

Thank you works great!

Close this issue if you like or if you prefer to keep it open.


Small addition to the set_readonly_keys would be to support dotlist style.

odelalleau commented 8 months ago

Close this issue if you like or if you prefer to keep it open.

I'll keep it open as I think it'd be good to make this possible without accessing the internal API.

Small addition to the set_readonly_keys would be to support dotlist style

This can probably be done by using select_node() (from omegaconf._impl import select_node), instead of _get_node().