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.