mrkeyoor.com_
Mon 21 Sept 02:03 UTC
PyPIUtilsupdated 20 Sept 2026

omegaconf review

OmegaConf 2.3.1 is a Python configuration tree for projects that combine YAML files, dataclass schemas, dictionaries, and command-line overrides. Its DictConfig and ListConfig containers support ordered merging, lazy references between values, environment lookups, mandatory placeholders, read-only trees, and rejection of unknown keys. Structured configs check assigned values against dataclass or attrs annotations at runtime. The current 2.3.1 release is a packaging fix for source installs on setuptools versions that removed pkg_resources; the configuration API remains on the 2.3 line. Our sandbox install was pure Python, included py.typed, and imported successfully.

Verdict

OmegaConf 2.3.1 installed in 1.7 seconds, occupied 4 MB across three packages, and produced zero audit findings in our sandbox, making its runtime cost modest for layered Python configuration. Install it when merging, interpolation, and dataclass-backed checks will all be used; a single YAML file does not justify its second object model.

We installed it

Lab card: what happened when we installed omegaconfScreenshot of omegaconf documentation
Install✓ · 1.7s3 packages on disk · 4 MB
Importimport omegaconf in 0.29s · pure Python · py.typed · requires Python >=3.6
Known vulns0(pip-audit)

Answers from our run

Does omegaconf install cleanly?

Yes. In a fresh container with an empty cache, pip install omegaconf finished in 2 seconds, leaving 3 packages and 4 MB on disk. pip-audit reported no known vulnerabilities.

What does omegaconf need to run?

Python >=3.6, and nothing compiled: it is pure Python. In our run import omegaconf succeeded in 0.29s, and the package ships py.typed for type checkers.

omegaconf or pydantic-settings: which should you use?

pydantic-settings: Choose it when Pydantic models and environment variables already define application settings. OmegaConf 2.3.1 installed in 1.7 seconds, occupied 4 MB across three packages, and produced zero audit findings in our sandbox, making its runtime cost modest for layered Python configuration.

When should you not use omegaconf?

Your program reads one fixed YAML file; PyYAML avoids OmegaConf's container types, flags, and interpolation syntax

API stability4/5OmegaConf's stable 2.3 interface still centers on `create`, `load`, `merge`, `structured`, interpolation resolvers, node flags, and conversion helpers. Release 2.3.1 changed source packaging without altering those configuration operations. The caution is version separation: 2.4 remains a development line with its own documentation, so examples found under `latest` can describe behavior that the stable 2.3.1 package does not provide.
Docs4/5The official 2.3 documentation has runnable sections for creation, YAML I/O, merging, interpolation, built-in and custom resolvers, missing values, structured configs, flags, selection, masking, and object conversion. Its version switcher matters because the README links both the stable 2.3 branch and upcoming 2.4 material. Search results do not always keep that boundary visible, so confirm the page version before copying an example.
Maintenance3/5Version 2.3.1 was published on 2026-06-11 to repair source installs after newer setuptools releases removed pkg_resources, and the repository was pushed on 2026-08-26. It is not archived, has 2,426 stars, and GitHub reports 31 open issues and pull requests. The gap between the 2022 release of 2.3.0 and this packaging-only update shows that stable feature releases arrive slowly even while development continues.
Ecosystem4/5The supplied registry figure is 10,075,938 weekly downloads, and OmegaConf is the configuration container used by Hydra. It accepts YAML, dictionaries, dataclasses, attrs classes, and command-line dotlists through one API, which fits Python experiment tooling well. General web applications have more surrounding integrations for Pydantic Settings or direct environment parsing, so OmegaConf's strongest ecosystem advantage appears in Hydra-based stacks.

Use it if

  • Your application composes defaults, environment files, and command-line dotlist overrides in a defined order
  • A dataclass should set the allowed configuration shape while YAML remains the format operators edit
  • Values need lazy references to sibling keys or environment variables before startup resolves the final tree
  • A Hydra application already hands your code DictConfig and ListConfig objects
Skip it if

Setup reality

We installed OmegaConf 2.3.1 in a clean Python 3.12 container in 1.7 seconds. The result was three packages using 4 MB on disk, and pip-audit reported zero known vulnerabilities. Package metadata counted three direct dependencies and allowed Python 3.6 or newer. It is pure Python, carries py.typed, and import omegaconf completed in 0.29 seconds. Check the exact antlr4-python3-runtime pin before adding it to an environment that already has parser tooling.

There is no account, credential, daemon, or required project file. Start with OmegaConf.load() for YAML or OmegaConf.structured() for a dataclass, then merge sources from lowest to highest priority. In a 3-layer setup, the rightmost input wins when the same mapping key appears again. Lists do not behave like recursively merged dictionaries, so test replacement semantics with your actual files.

Interpolations resolve when a value is read. A missing ${oc.env:NAME}, a resolver exception, a reference cycle, or a ??? placeholder can therefore remain hidden during construction. Check OmegaConf.missing_keys() after the final merge and resolve or convert the tree at startup when configuration errors should stop the process. The oc.env resolver returns text; wrap it with oc.decode when YAML-style conversion to a number or boolean is intended.

Type checking a structured config does not turn DictConfig into the original dataclass. Use OmegaConf.to_object() when an API expects dataclass instances, or to_container(resolve=True) when it expects built-in collections. Resolver registration is process-wide, and a duplicate name raises unless replace=True is deliberate. Hydra pins a compatible OmegaConf range, so upgrade the pair together instead of forcing 2.3.1 into an unmatched Hydra environment.

Patterns

Build a nested configuration tree create-config

from omegaconf import OmegaConf

cfg = OmegaConf.create({
    "server": {"host": "127.0.0.1", "port": 8000},
    "features": ["search", "billing"],
})
print(cfg.server.port)
print(cfg["features"][0])

Nested mappings and lists become DictConfig and ListConfig objects. Both attribute access and item access operate on the configuration nodes.

Apply file and CLI overrides in priority order merge-overrides

from omegaconf import OmegaConf

base = OmegaConf.load("config/base.yaml")
environment = OmegaConf.load("config/production.yaml")
cli = OmegaConf.from_cli()
cfg = OmegaConf.merge(base, environment, cli)

Later inputs win for repeated mapping keys. `from_cli()` reads the process argument list, so coordinate it with argparse or another CLI parser.

Check file values against a dataclass validate-dataclass

from dataclasses import dataclass
from omegaconf import OmegaConf

@dataclass
class ServerConfig:
    host: str = "127.0.0.1"
    port: int = 8000

schema = OmegaConf.structured(ServerConfig)
file_values = OmegaConf.load("server.yaml")
cfg = OmegaConf.merge(schema, file_values)

Place the schema first and user values later. Invalid assignments raise during the merge, while the merged result remains a DictConfig.

Compose nested typed sections nest-structured-configs

from dataclasses import dataclass, field
from omegaconf import OmegaConf

@dataclass
class Database:
    url: str = "sqlite:///app.db"

@dataclass
class AppConfig:
    debug: bool = False
    database: Database = field(default_factory=Database)

cfg = OmegaConf.structured(AppConfig)

Use `default_factory` for nested mutable defaults. OmegaConf reads the field annotations to validate later assignments inside each section.

Derive one path from another setting reference-values

from omegaconf import OmegaConf

cfg = OmegaConf.create({
    "root": "/srv/example",
    "uploads": "${root}/uploads",
})
print(cfg.uploads)

Interpolation is lazy. Changing `root` changes the value returned for `uploads` until the configuration is explicitly resolved or converted.

Read environment values with defaults and conversion read-environment

from omegaconf import OmegaConf

cfg = OmegaConf.create({
    "host": "${oc.env:APP_HOST,127.0.0.1}",
    "port": "${oc.decode:${oc.env:APP_PORT,8000}}",
    "token": "${oc.env:APP_TOKEN}",
})

`oc.env` returns strings and raises when a variable has no value or default. `oc.decode` parses YAML-style scalar text such as `8000` or `true`.

Find mandatory values before startup continues reject-missing-values

from omegaconf import MISSING, OmegaConf

cfg = OmegaConf.create({"database": {"password": MISSING}})
missing = OmegaConf.missing_keys(cfg)
if missing:
    names = ", ".join(sorted(missing))
    raise RuntimeError(f"Missing configuration: {names}")

A mandatory value is written as `???` in YAML. Reading one raises MissingMandatoryValue, while `missing_keys()` lets startup report the full set first.

Register a calculated interpolation register-resolver

from omegaconf import OmegaConf

OmegaConf.register_new_resolver(
    "times",
    lambda left, right: left * right,
    use_cache=True,
)
cfg = OmegaConf.create({"workers": "${times:2,4}"})
print(cfg.workers)

Resolver names share process-wide state. Registering an existing name raises ValueError unless replacement is explicitly requested.

Block new keys and later mutation freeze-config

from omegaconf import OmegaConf

cfg = OmegaConf.create({"model": {"rate": 0.01}})
OmegaConf.set_struct(cfg, True)
OmegaConf.set_readonly(cfg, True)

# cfg.model.rtae = 0.1 raises ConfigAttributeError
# cfg.model.rate = 0.2 raises ReadonlyConfigError

Set both flags after all intended merges. Struct mode rejects unknown keys, while read-only mode rejects changes to existing values.

Return plain collections or dataclass objects convert-output

plain = OmegaConf.to_container(cfg, resolve=True)
typed = OmegaConf.to_object(cfg)
yaml_text = OmegaConf.to_yaml(cfg, resolve=True)

`to_container` returns built-in dictionaries and lists. `to_object` creates instances for structured nodes and also resolves interpolations.

Read and write a dotted path select-update-path

from omegaconf import OmegaConf

cfg = OmegaConf.create({"service": {"timeout": 10}})
timeout = OmegaConf.select(cfg, "service.timeout", default=30)
OmegaConf.update(cfg, "service.timeout", 15)
OmegaConf.update(cfg, "service.retries", 3, force_add=True)

`select` can supply a default for an absent path. `force_add=True` deliberately bypasses struct restrictions when adding a new path.

Write and reload YAML save-config

from omegaconf import OmegaConf

OmegaConf.save(config=cfg, f="effective.yaml", resolve=True)
loaded = OmegaConf.load("effective.yaml")

Saving with `resolve=True` writes resolved values rather than interpolation expressions. The YAML round trip does not preserve structured config type information.

Alternatives

PackageRegistryPick it when
pydantic-settingsPyPIChoose it when Pydantic models and environment variables already define application settings.
dynaconfPyPIChoose it for named environments, layered files, and integrations with external secret stores.
hydra-corePyPIChoose it when the application also needs config groups, launch management, and parameter sweeps.
pyyamlPyPIChoose it when parsing and writing plain YAML is enough and no composition system is wanted.

More utils guides

lru-cache · ajv · type-fest · p-limit · find-up · js-yaml · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.