CONCEPTS

Config as Python

Config as Python

Tutorial: Why Laco?See also: Lie-Typing, API: laco.load

Why Python Files?

Traditional config systems use YAML or JSON. Those formats can only represent primitives, lists, and dicts. Referring to a class like torch.nn.ReLU requires a magic string ("torch.nn.ReLU") that silently breaks on rename.

Laco config files are real .py files. You get:

  • Real imports: if torch.nn.ReLU is renamed, import fails loudly at load time
  • IDE go-to-definition, autocomplete, and refactoring on config targets
  • Arbitrary Python expressions for derived values
  • No separate config DSL to learn

The trade-off: configs are code, so the same discipline applies (version control, code review, reproducibility via pinned deps).

How laco.load Works

cfg = laco.load("configs/mlp.py")

Internally:

  1. The .py file is read and compiled.
  2. A controlled exec runs the module in a namespace with _patch_import active, so relative imports within config packages resolve correctly.
  3. Names in __all__ (or all non-underscore names if __all__ is absent) are exported as keys in a DictConfig.
  4. Each exported value is recursively converted: DictConfig nodes are spliced in; primitives are kept; other objects raise TypeError unless they are LazyObject nodes produced by L.call and friends.

The configs:// Protocol

Laco registers a path handler with expath so that configs:// URLs resolve against the installed laco.examples package:

cfg = laco.load("configs://examples/mlp.py")

Your own project can register additional configs:// namespaces via the [project.entry-points.configs] table in pyproject.toml:

[project.entry-points.configs]
my_project = "my_project.configs"

Then laco.load("configs://my_project/train.py") resolves to the my_project/configs/train.py file inside the installed package.

YAML Round-Trip

cfg = laco.load("configs/mlp.py")
laco.dump(cfg)           # → Hydra-compatible YAML string
laco.save(cfg, "run/config.yaml")   # → file on disk
cfg2 = laco.load("run/config.yaml") # ← load the YAML back

YAML configs produced by laco.dump include a _laco_: 1 schema-version marker stripped on load. They are valid Hydra YAML and can be consumed by any Hydra application.

LoadMode

cfg = laco.load("configs/mlp.py", mode=laco.LoadMode.SAFE)

LoadMode.SAFE removes dangerous builtins (open, eval, exec, …) and enforces a module allowlist. Use it when loading configs from untrusted sources. See How-To: Safe Loading.