HOW-TO

Lint and Strict Mode

Lint and Strict Mode

See also: Concepts: Lie-Typing, API: compat

LACO_STRICT_NODES

Set the environment variable to raise immediately if code treats a Laco node as if it were the real object:

LACO_STRICT_NODES=1 python train.py

Without this flag, accessing an attribute not present on a DictConfig returns the OmegaConf default (??? or raises MissingMandatoryValue). With it, attribute access on a node outside recognized config keys raises AttributeError immediately with a helpful message.

Use LACO_STRICT_NODES=1 in development; disable in production (it adds overhead on every attribute access).

laco-lint

laco-lint is a static analysis tool that detects lie-typing violations:

laco-lint sources/           # lint all Python files under sources/
laco-lint configs/train.py   # lint a single file

LACO001

LACO001 fires when a value annotated as a Laco node type (e.g. LazyObject[T], a DictConfig returned by L.call) is used in a context that requires the real object (attribute access, method call).

Suppress intentionally:

node = L.call(nn.Linear)(784, 10)
# Intentional: reading config metadata, not the nn.Linear interface
size = node._metadata["out_features"]  # noqa: LACO001

CI Integration

Add laco-lint to your lint step alongside ruff:

# .github/workflows/lint.yml
- run: |
    ruff check sources/
    laco-lint sources/

Or in a Makefile:

lint:
    ruff check sources/
    laco-lint sources/

LACO_TRACE

Set LACO_TRACE=1 to log every laco.instantiate call with its full config tree (at INFO level). Useful for debugging instantiation order:

LACO_TRACE=1 python train.py 2>&1 | grep "Instantiating"