-
Notifications
You must be signed in to change notification settings - Fork 149
Description
Long time OmegaConf user, first time participating here. Thanks for the great project. :)
The problem
OmegaConf keypaths always use one of :, ., or [ ] as delimiters when parsing nested updates.
Additionally, YAML allows these characters in keys. In some cases this is an obvious observation. In cases with : it's less obvious, but still possible. For a valid example:
some_settings:
"mm(1:3)": 42I'm working in a use case where I need to load a large number of configuration files into OmegaConf, but many of these files contain keys that include special characters :, ., [, and ]. Unfortunately, OmegaConf interprets these characters as structural markers for nested keypaths.
This creates ambiguity when trying to reference or update values using OmegaConf.update(). Any string passed to the update function is parsed by split_key(), which treats these characters as delimiters for nested keypaths -- even when they are meant to be literal characters within a single key.
OmegaConf.update(cfg, "some_settings:mm(1:3)", ...) # ambiguous if key is mm(1:3) <-- this is my current issue
OmegaConf.update(cfg, "some_settings[mm(1:3)]", ...) # still parsed
OmegaConf.update(cfg, "some_settings[mm[1:3]]", ...) # ambiguous if key is mm[1:3]
OmegaConf.update(cfg, "some_settings.mm(1:3)", ...) # still parsed
OmegaConf.update(cfg, "some_settings.mm(1.3)", ...) # ambiguous if key is mm(1.3)Proposal
Allow OmegaConf.update() to accept a list of literal key segments:
OmegaConf.update(
cfg,
["some_settings", "mm(1:3)"],
99
)This would bypass split_key() entirely and treat the path as explicit and literal. I think/hope this would also be fully backward-compatible, since existing split_key() already returns a list.
Minimal code change
In OmegaConf.update change the key handling from
split = split_key(key)to:
split = key if not isinstance(key, str) else split_key(key)This retains all existing behavior for string keypaths, while allowing unambiguous literal keypaths when a list is passed. I'm uncertain if this would interfere with the actual updating though.
What I've already considered:
- Escaping characters inside the keypath string (
mm(1\:3)) — does not work, becausesplit_key()recognizes multiple delimiters. - Using bracket notation -- also gets parsed before brackets are interpreted.
- Manually walking the tree and inserting values. functional but requires reimplementing OmegaConf’s merge semantics.
I'm happy to implement this and open a PR if devs agree/support this request!