omry / omegaconf

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

Resolver for obtaining key names #1085

Closed MatteoVoges closed 1 year ago

MatteoVoges commented 1 year ago

Is your feature request related to a problem? Please describe. Does OmegaConf support obtaining key names with interpolation and references?

Describe the solution you'd like For example:

key: ${.self.name}

The interpolation would resolve to key. Note, that the interpolation is not a relative interpolation, so the syntax isn't ideal here. A better way would be a build-in resolver like ${key_name: <path_to_key>}. In this case the path would be just ..

This would be really useful for large parameterized configs, because then you can refer to the keyname instead of having an extra value for that.

omry commented 1 year ago

You should be able to implement something using custom resolvers.

In particular, you can pass _parent_ to your resolver to receive the parent node: Custom interpolations can also receive the following special parameters: _parent_: The parent node of an interpolation. _root_: The config root.

There is another special value you can use which is _node_ (undocumented for some reason).

from omegaconf import OmegaConf, Node

def key(_node_: Node):
    return _node_._key()

def fullkey(_node_: Node):
    return _node_._get_full_key("")

OmegaConf.register_new_resolver("key", key)
OmegaConf.register_new_resolver("fullkey", fullkey)

cfg = OmegaConf.create({
    "foo": {
        "bar": {
            "key": "${key:}",
            "fullkey": "${fullkey:}"
        }
    }
})

print(cfg.foo.bar.key)
# key
print(cfg.foo.bar.fullkey)
# foo.bar.fullkey
MatteoVoges commented 1 year ago

Thanks, I thought exactly about something like that.

MatteoVoges commented 1 year ago

Should I add this in the docs?

Jasha10 commented 1 year ago

@MatteoVoges that would be appreciated.

omry commented 1 year ago

I think the reason it's not documented is that entire Node class is not public API and is not documented. Making use of it is by definition using private API.

Jasha10 commented 1 year ago

entire Node class is not public API and is not documented

Oh, right. Nevermind about the docs @MatteoVoges.