omry / omegaconf

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

Add function to check if key exists #1129

Open IararIV opened 1 year ago

IararIV commented 1 year ago

Issue Description

Feature Request: Add a built-in function to check if a key exists in OmegaConf.

Current Workaround: Currently, users need to resort to a workaround, as demonstrated below, to check if a key exists:

# Check that key exists in the config. OmegaConf doesn't have a builtin function to check for keys
UNDEFINED_VALUE = 3430323896892821
assert OmegaConf.select(cfg, key, default=UNDEFINED_VALUE) != UNDEFINED_VALUE, \
    f"Key {key} doesn't exist in the configuration!"

Suggested Enhancement

It would be beneficial to have a dedicated function or method in OmegaConf to easily check for the existence of a key within a configuration, similar to how many other configuration libraries or dictionaries support key existence checks.

Expected Behavior

Ideally, a new function or method, let's say key_exists(key), could be added to OmegaConf, allowing users to check if a key exists within the configuration. For example:


if OmegaConf.key_exists(cfg, key):
    # Key exists in the configuration
else:
    # Key doesn't exist in the configuration

This enhancement would improve the usability and readability of OmegaConf code by eliminating the need for workarounds.

Environment

OmegaConf version: 2.3.0
Python version: 3.11.4
odelalleau commented 1 year ago

You should be able to use key in cfg to test for the existence of a key.

IararIV commented 1 year ago

It works for main keys, but it doesn't work when going in deeper levels:

from omegaconf import OmegaConf

config = OmegaConf.create({'model': {'name': 'resnet', 'num_layers': 50}})

config.model.name
# 'resnet'

"model" in config
# True

"model.name" in config
# False

Is there a way to do it that I'm not aware of?

odelalleau commented 1 year ago

Oh I see, indeed I don't think such a function exists right now.

Note that technically model.name is not a key of config (because config["model.name"] doesn't exist). Just something to keep in mind regarding the naming of such a function.

IararIV commented 1 year ago

Yes, you're right. What I'd expect is the implementation to reuse what OmegaConf.select uses internally to look for nodes.

OmegaConf.select(config, "model.name")
# 'resnet'

OmegaConf.key_exists(cfg, "model.name")
# True

OmegaConf.key_exists(cfg, "model.age")
# False