Skip to main content
Version: 2.3

Built-in resolvers

Resolver calls use ${name:arguments} and evaluate when their node is read. They can be nested. These resolvers are available without registration:

ResolverUse
oc.envRead an environment variable, with an optional default.
oc.createConvert a resolver result or YAML string to a config node.
oc.deprecatedWarn on an old key and forward to a replacement.
oc.decodeParse a string with OmegaConf's interpolation grammar.
oc.selectSelect a key, optionally returning a default.
oc.dict.keys / oc.dict.valuesView dictionary keys or values as a list config.

oc.env​

${oc.env:NAME,default} reads an environment variable. The default is stringified unless it is null, which produces None. Environment values are strings; use oc.decode when you need another type.

>>> import os
>>> from omegaconf import OmegaConf
>>> os.environ["OC_DOCS_PORT"] = "8080"
>>> cfg = OmegaConf.create({
... "raw": "${oc.env:OC_DOCS_PORT}",
... "converted": "${oc.decode:${oc.env:OC_DOCS_PORT}}",
... })
>>> cfg.raw, cfg.converted
('8080', 8080)
>>> del os.environ["OC_DOCS_PORT"]

oc.create​

${oc.create:${some_resolver:}} turns a returned dictionary, list, or YAML string into an OmegaConf container. This makes its nested values accessible as config nodes.

>>> OmegaConf.register_new_resolver("make_docs_mapping", lambda: {"answer": 42})
>>> cfg = OmegaConf.create({
... "plain": "${make_docs_mapping:}",
... "created": "${oc.create:${make_docs_mapping:}}",
... })
>>> type(cfg.plain).__name__, type(cfg.created).__name__
('dict', 'DictConfig')
>>> cfg.created.answer
42

oc.deprecated​

${oc.deprecated:new_key} warns when the old key is read and returns the new key's value. An optional second argument customizes the warning text; $OLD_KEY and $NEW_KEY are replaced in that text.

>>> import warnings
>>> cfg = OmegaConf.create({
... "old": "${oc.deprecated:new}",
... "new": 42,
... })
>>> with warnings.catch_warnings(record=True) as emitted:
... warnings.simplefilter("always")
... value = cfg.old
>>> value, len(emitted)
(42, 1)

oc.decode​

${oc.decode:${oc.env:PORT}} parses a string using the interpolation grammar. It recognizes numbers, booleans, lists, and dictionaries. Quote input strings containing grammar punctuation. null is the only non-string input and returns None.

>>> cfg = OmegaConf.create({
... "ports": "${oc.decode:'[80, 443]'}",
... "disabled": "${oc.decode:null}",
... })
>>> cfg.ports, cfg.disabled
([80, 443], None)

oc.select​

${oc.select:path,default} reads a path and supplies a default when the path is absent or missing. Unlike ordinary node interpolation, it can return a default instead of raising. Quote paths containing resolver punctuation.

>>> cfg = OmegaConf.create({
... "required": "???",
... "fallback": "${oc.select:required,localhost}",
... "unfilled": "${oc.select:required}",
... })
>>> cfg.fallback, cfg.unfilled
('localhost', None)

In 2.3, oc.select also reaches keys that ordinary node-interpolation syntax cannot express. A colon would otherwise be parsed as a resolver call:

>>> cfg = OmegaConf.create({
... "a:b": 10,
... "selected": "${oc.select:'a:b'}",
... })
>>> cfg.selected
10

oc.dict.keys and oc.dict.values​

${oc.dict.keys:workers} returns a ListConfig of dictionary keys; ${oc.dict.values:workers} returns a ListConfig whose elements track the dictionary values. Both accept a path to a DictConfig.

>>> cfg = OmegaConf.create({
... "workers": {"first": "host-a"},
... "names": "${oc.dict.keys:workers}",
... "hosts": "${oc.dict.values:workers}",
... })
>>> list(cfg.names), list(cfg.hosts)
(['first'], ['host-a'])
>>> cfg.workers.first = "host-b"
>>> list(cfg.hosts)
['host-b']