Work with dots in keynames
MatteoVoges opened this issue · comments
Is your feature request related to a problem? Please describe.
Is there a way to work with dots in keys, where the dots are part of the key and not function as path delimiter?
Describe the solution you'd like
Example:
labels:
app.kubernetes.io/name: mylabel
reference: ${labels.app.kubernetes.io/name}
The goal would be to have reference
resolved as mylabel
.
I know that this is a tricky one, because the dot is the path delimiter, but I am thinking of a modification of the config creation like in the function OmegaConf.from_dotlist()
, so that in fact the DictConfig
{"labels": {"app": {"kubernetes": {"io/name": "mylabel"}}}}
gets created and the interpolation can get resolved correctly.
OmegaConf does not entirely prevent using dots in key names: if you load your config, you should be able to access cfg.labels["app.kubernetes.io/name"]
. This also means we can't automatically do what you're suggesting (this would break existing code relying on this feature).
An ugly workaround is to do something like:
labels:
app.kubernetes.io/name: ${._app_kubernetes_io_name}
_app_kubernetes_io_name: mylabel
reference: ${labels._app_kubernetes_io_name}
but it's unlikely to be what you're looking for.
Your best bet is probably to figure out how to change the yaml yourself (possibly in an automated way) so that it becomes
labels:
app:
kubernetes:
io/name: mylabel
reference: ${labels.app.kubernetes.io/name}
(or, write your own loader for your yaml file, generate the dict
you want to use and pass it to OmegaConf.create()
)
Thank you for your answer. Do you have any ideas in mind how to achieve this behavior with a custom resolver? Maybe if we pass a list of all real parts of the key (i.e. labels
, app.kubernetes.io/name
) and access them with your proposed method using []
.
Do you have any ideas in mind how to achieve this behavior with a custom resolver?
Hmm, I think you can probably achieve something that would look like either
labels:
app.kubernetes.io/name: some_name
_labels: ${my_custom_resolver: ${labels}} # convert it to DictConfig without dots in key names
reference: ${_labels.app_kubernetes_io/name}
or
labels:
app:
kubernetes:
io/name: some_name
_labels: ${my_custom_resolver: ${labels}} # convert it to DictConfig with dots in key names
reference: ${labels.app_kubernetes_io/name}
This could be achieved with a custom resolver that returns a DictConfig (one example here: https://github.com/omry/omegaconf/blob/master/omegaconf/resolvers/oc/__init__.py#L14)
(the second example is in case you need to recover the "original" format -- I'm not sure if it matters in your use case)
Maybe if we pass a list of all real parts of the key (i.e.
labels
,app.kubernetes.io/name
) and access them with your proposed method using[]
I'm not sure I understand what you have in mind here.
Good idea with converting the key into a nested config, especially, because I could use from_dotlist()
in the resolver, right?
I'm not sure I understand what you have in mind here.
def access_key_with_dots(parts*):
reference = config # get the config (idk, like in oc.select)
for part in parts:
reference = reference[part] # get element by whole key with brackets
return reference
And now I could use the resolver like:
reference: ${access_key_with_dots:labels,app.kubernetes.io/name} # should get resolved into mylabel
Alternatively we could pass the last key without a dot into the resolver and access it directly:
def access_key_with_dots(config: DictConfig, key_with_dots: str):
return config[key_with_dots]
Usage:
reference: ${access_key_with_dots:${labels},app.kubernetes.io/name}
Ah, yes, you could indeed write a custom version of oc.select
to achieve what you want!
Thanks again for your help and ideas. For me, the workaround using the resolver is fine, so I would close the issue.