Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: Key-based readonly flag. #1161

Open
Daraan opened this issue Feb 28, 2024 · 3 comments
Open

Feature Request: Key-based readonly flag. #1161

Daraan opened this issue Feb 28, 2024 · 3 comments

Comments

@Daraan
Copy link

Daraan commented Feb 28, 2024

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 ...
  • Future: On top of 2) metadata could be used to indicate readonly keys:
protected_value : float = field(default=SI("..."), metadata={"omegaconf_readonly_key"})

Do you think 2) is a possible solution?

@odelalleau
Copy link
Collaborator

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
Copy link
Author

Daraan commented Feb 29, 2024

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
Copy link
Collaborator

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().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants