Skip to content

launch: thread "expects options" flag through type_map instead of runtime hasattr #361

@gilesknap

Description

@gilesknap

Context

Follow-up cleanup from PR #360 (slice #354 — multi-class launch()).

_build_entry_model decides at build time whether a registered Controller class takes an options arg, by either adding a controller field to its entry model or not. Then _instantiate_controllers re-discovers that decision at runtime via hasattr(entry, "controller"):

# src/fastcs/launch.py:184-203
for id, entry in controllers_options.items():
    cls = type_map[entry.type]
    if hasattr(entry, "controller"):
        controller = cls(entry.controller)
    else:
        controller = cls()
    controller.set_id(id)
    controllers.append(controller)

It works, but the build-time and runtime branches are kept in sync only by duck-typing on a dynamic Pydantic model. Touching either side without the other is a silent footgun.

What to build

Thread the "this class expects options" flag forward from _build_entry_model so _instantiate_controllers reads off the same source of truth. Two reasonable shapes:

  • type_map: dict[str, tuple[type[Controller], bool]] keyed by discriminator, value = (class, expects_options)
  • A tiny _RegisteredClass dataclass with cls, expects_options (and any future per-class metadata)

Either way, the hasattr check goes away and _instantiate_controllers becomes data-driven.

Acceptance criteria

  • _instantiate_controllers no longer uses hasattr on the entry model
  • Build-time and instantiate-time decisions about "options arg present?" share one source of truth
  • Existing tests/test_launch.py cases still green; no behaviour change for users
  • Full test suite stays green

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions