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

Possible edge case: interpolation to key containing a colon #680

Closed
Jasha10 opened this issue Apr 15, 2021 · 7 comments
Closed

Possible edge case: interpolation to key containing a colon #680

Jasha10 opened this issue Apr 15, 2021 · 7 comments

Comments

@Jasha10
Copy link
Collaborator

Jasha10 commented Apr 15, 2021

It is not uncommon to see config files that contain a value with a colon, e.g. "<ip_address>:<port_number>". It is probably much less common to see a colon as part of a key in a config file. An edge case can arise when interpolating to a key that contains a colon, since OmegaConf uses colons for its resolver syntax.

Here is what will happen if you try to do this:

$ cat tmp.py
from omegaconf import OmegaConf
cfg = OmegaConf.create({"fo:o": 123, "bar": "${fo:o}"})
print(cfg.bar)
$ python tmp.py
Traceback (most recent call last):
...
omegaconf.errors.UnsupportedInterpolationType: Unsupported interpolation type fo
    full_key: bar
    object_type=dict

If a resolver is registered with a name that equals the part of the key before the colon, you will get this behavior:

$ cat tmp2.py
from omegaconf import OmegaConf
cfg = OmegaConf.create({"fo:o": 123, "bar": "${fo:o}"})
OmegaConf.register_new_resolver("fo", lambda x: 456)
print(cfg.bar)
$ python tmp2.py
456

I am posting this issue so that there will be documentation for this possible edge case.

@omry
Copy link
Owner

omry commented Apr 15, 2021

Nice catch.
In theory it's possible to support it by escaping the : "${fo:o}"
or by quoting the interpolation string: ${'fo:o'}.
None of those is working right now and I don't think it's an important enough use case.

OmegaConf never supported it and there have been no user reports about it.

@odelalleau
Copy link
Collaborator

In case someone runs into this issue, there are at least a few workarounds:

# Workaround 1: create a variable to hold the key name
cfg = OmegaConf.create({"fo:o": 123, "bar": "${${bar_ref}}", "bar_ref": "fo:o"})

# Workaround 2: use `oc.decode` (@omry so actually it *is* useful with literal strings!)
cfg = OmegaConf.create({"fo:o": 123, "bar": "${${oc.decode:'fo:o'}}"})

# Workaround 3: use a "select" resolver to manually select arbitrary nodes (maybe later we'll have `oc.select`)
OmegaConf.register_new_resolver("select", lambda key, _parent_: OmegaConf.select(_parent_, key))
cfg = OmegaConf.create({"fo:o": 123, "bar": "${select:'fo:o'}"})

@omry
Copy link
Owner

omry commented Apr 17, 2021

I think #687 is addressing this.

@omry
Copy link
Owner

omry commented Apr 28, 2021

@Jasha10, if you agree - let's close this.

@Jasha10
Copy link
Collaborator Author

Jasha10 commented Apr 29, 2021

I am confused about how #687 is addressing this. After merging #687, the examples from the top of this issue still give the same output as before.

@omry
Copy link
Owner

omry commented Apr 29, 2021

@Jasha10
Copy link
Collaborator Author

Jasha10 commented Apr 29, 2021

Oh, got it :)
Ok, closing now.

@Jasha10 Jasha10 closed this as completed Apr 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants