You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
ControllerFiller mirroring ophyd_asyncDeviceFiller (core/_device_filler.py — follow its structure; match names only where FastCS vocab fits). Scans class hints for AttrR/W/RW[T], Command[...], sub-Controller/ControllerVector[T]; creates children unfilled; check_filled(source) reports promised-but-missing.
Rule: at the end of __init__, any Attribute referenced in code (i.e. type-hinted) MUST exist; initialise() may then run in parallel (only __init__ is serial). (0013 L150)
Support: no-hints-at-all (0013 L139); Optional[X] hints (0013 L153); adding attributes onto a bare Controller from outside — which is what fillers do (0013 L144).
yields (child, extras) so third-party extras vocabularies work (decision 3); core defines none. Delete HintedAttribute + _validate_type_hints; remove the deepcopy half of _bind_attrs (keep @command/@scan binding). Trailing-underscore name convention.
fastcs-catio builds Controller classes at runtime via type(...) from YAML before any instance exists — decide: does the filler support class-level dynamic construction, or must catio move to instance-level dynamic attrs? Record the decision in the PR / an ADR update.
Key files (§9)
controllers/base_controller.py (_bind_attrs, _find_type_hints), + new filler module.
Acceptance
uv run --locked tox -e pre-commit,type-checking,tests green; Example 5 updated + green.
Filler metadata validation — folded in from review
Hinted children are created unfilled in __init__ (so they exist after __init__, per the ADR 13 rule); initialise() only fills them (+ may add unhinted dynamic attrs).
When filling from an Annotated[Attr[T], extras] hint, runtime-validate the metadata the extras carries (FloatMeta, or a protocol object's .meta e.g. SCPIParam(...).meta) against datatype T — precision on a str raises. Runtime counterpart to the static Unpack[FloatMeta] check (getter/setter IO rework; remove AttributeIORef and AttributeIO #392).
Scope
ControllerFillermirroringophyd_asyncDeviceFiller(core/_device_filler.py— follow its structure; match names only where FastCS vocab fits). Scans class hints forAttrR/W/RW[T],Command[...], sub-Controller/ControllerVector[T]; creates children unfilled;check_filled(source)reports promised-but-missing.__init__, any Attribute referenced in code (i.e. type-hinted) MUST exist;initialise()may then run in parallel (only__init__is serial). (0013 L150)Optional[X]hints (0013 L153); adding attributes onto a bareControllerfrom outside — which is what fillers do (0013 L144).yields (child, extras)so third-party extras vocabularies work (decision 3); core defines none. DeleteHintedAttribute+_validate_type_hints; remove the deepcopy half of_bind_attrs(keep@command/@scanbinding). Trailing-underscore name convention.fastcs-catiobuilds Controller classes at runtime viatype(...)from YAML before any instance exists — decide: does the filler support class-level dynamic construction, or must catio move to instance-level dynamic attrs? Record the decision in the PR / an ADR update.Key files (§9)
controllers/base_controller.py(_bind_attrs,_find_type_hints), + new filler module.Acceptance
uv run --locked tox -e pre-commit,type-checking,testsgreen; Example 5 updated + green.ADR: 0013
Parent: #388
Blocked by: #392, #413
Filler metadata validation — folded in from review
__init__(so they exist after__init__, per the ADR 13 rule);initialise()only fills them (+ may add unhinted dynamic attrs).Annotated[Attr[T], extras]hint, runtime-validate the metadata the extras carries (FloatMeta, or a protocol object's.metae.g.SCPIParam(...).meta) against datatypeT—precisionon astrraises. Runtime counterpart to the staticUnpack[FloatMeta]check (getter/setter IO rework; remove AttributeIORef and AttributeIO #392).