DiamondLightSource / DiamondLightSource/fastcs

SPIKE (Opus/local): typed-command keyword-arg support via TYPE_CHECKING stub

Open
#403 1 comment 0 reactions 0 assignees View on GitHub
spike
Dominant language
Python
Stars
6
Forks
8
Avg merge
2d 12h
Merged PRs (30d)
3

Description

**Not for the autonomous nightly job** — interactive, Opus-driven local spike (fast pyright feedback loop). Deliberately NOT labelled `api-convergence`.

## Context
Follow-up to #393 (typed commands). Core typed commands (ADR 0015 / #388 decision 5), in scope for #393 autonomously, cover:
- Args: `[]` | `[DT1, DT2, …]` (positional, known types)
- Returns: `None` | `DT` (0015 L97)

There is **no `Command[Any, Any]`** — a statically-declared command has fully-known `P`/`T`; a driver that knows nothing statically builds the whole controller (commands included) at runtime. So this spike is *not* about a partially-typed command; it is purely about the **keyword-arg** spelling on an otherwise fully-known signature.

## The spike
Keyword-argument commands are the hard part. coretl's sketch (0015 L91):
```python
def fn_spec(named_arg: float) -> int: ...

if TYPE_CHECKING:
def command_spec(spec: Callable[P, T]) -> Command[P, T]: ...
# runtime equivalent TBD

kw_known = command_spec(fn_spec)
```
Prototype a spelling giving pyright-checked keyword args on a typed command, with a runtime that builds the `Command`. Ref: bluesky/ophyd-async#1138 (discussion r2965959411).

## Resolved: no `Command[Any, Any]` needed
@Tom-Willemsen confirmed on [#402](https://github.com/DiamondLightSource/fastcs/pull/402#discussion_r3621453680) that SECoP devices are discovered entirely from an over-the-wire `describe` — you never statically know something is a command without also knowing its signature. There is no "known command, unknown args" middle case, so runtime `Command[Any, Any]` introspection is *not* a requirement. Fully-dynamic drivers build their commands programmatically at runtime (each with a concrete signature from the wire `datainfo`); statically-declared controllers get fully-known `Command[P, T]`. This spike therefore stands on its own merits — pyright-checked **keyword args** for statically-declared typed commands — rather than as an alternative to `Any`.

## When / How
Non-blocking; best *after* #393 core lands so you prototype against the real `Command[P, T]`. Fresh Claude Code **Opus** session pointed at this issue, scratch branch, tight `pyright` loop. Fold back as a follow-up PR to `refactor`.

Contributor guide

Open the contributing guide

Research direction

Read ADR 0015 and follow #393 so the prototype uses the real Command[P, T] shape. Use a scratch branch and a tight pyright loop to test the TYPE_CHECKING command_spec spelling for keyword arguments, then determine how the runtime builds the Command. Done means pyright checks the keyword arguments and the runtime behavior is demonstrated for a fully known signature.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend-api-design
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.