Typing

Config uses Pydantic’s dataclass transform for ordinary construction. The two lifecycle methods return Self:

work = Model.config_draft()       # inferred as Model
final = work.config_finalize()    # inferred as Model

Static typing intentionally does not distinguish an unbound template, draft, or final. Child() retains the static type Child even when missing parent context causes the narrow runtime template fallback. The same typed object flows through project mutators, while lifecycle misuse fails at runtime.

def resnet50(cfg: Model, *, dim: int = 256) -> Model:
    cfg.dim = dim
    return cfg

Draft field assignments are checked against declared field types. Runtime draft assignment remains unvalidated, so a suppressed type error still fails during finalization.

Typed interpolation context

Pass the expected Config type to a selector for checked field access:

class Leaf(C.Config):
    copied: int = C.interp(lambda context: context.parent(Model).dim)

current(Model), parent(Model), parent(2, Model), root(Run), and nearest(Model) return the requested static type. Selector reachability and field declaration order remain runtime properties.

Annotation evaluation

Normal eager annotations, explicit quoted forward references, and from __future__ import annotations are all supported across Python 3.10 through 3.14. The optional trusted cloudpickle transport also supports these forms for notebook-local Config classes.

Name resolution otherwise follows Pydantic. If an annotation refers to a name that is still unavailable when the class is created, define the name and call ConfigType.model_rebuild() using the same rules as an ordinary Pydantic model.

Names used only inside an interpolation lambda are resolved when the callable runs, so a later parent class may be referenced without turning the field annotation into a string. During the parent class body, the first unresolved NameError creates an unbound child template; binding reruns the callable after the parent name exists. A repeated NameError then fails validation normally.

Supported checker

basedpyright is the checked contract. The repository includes positive and negative golden probes under tests/typing_probes/. Diagnostic changes are treated as typing behavior changes.