Config Data Classes ==================== .. toctree:: :maxdepth: 2 Overview -------- ``ska_tmc_common.v4.ska_device_config`` groups the settings that TMC component managers need into a small hierarchy of ``dataclasses`` instead of long, error-prone constructor argument lists. A component manager takes a single config object, and every config class in the hierarchy is built by inheriting only the fields that class actually needs: * ``TimeoutConfig`` -- timeout and polling-period settings shared by every TMC component manager. * ``TelmodelConfig`` -- Telescope Model source/path settings. * ``BaseTmcComponentManagerConfig`` -- settings common to both node and leaf node component managers (extends ``TimeoutConfig``). * ``TmcComponentManagerConfig`` -- adds the node-specific settings (``component``) on top of ``BaseTmcComponentManagerConfig``. * ``TmcLeafNodeConfig`` -- the leaf node specific config, also extending ``BaseTmcComponentManagerConfig``. .. contents:: :local: :depth: 2 1. TimeoutConfig ----------------- .. autoclass:: ska_tmc_common.v4.ska_device_config.TimeoutConfig :members: :undoc-members: 2. TelmodelConfig ------------------- .. autoclass:: ska_tmc_common.v4.ska_device_config.TelmodelConfig :members: :undoc-members: 3. BaseTmcComponentManagerConfig ----------------------------------- .. autoclass:: ska_tmc_common.v4.ska_device_config.BaseTmcComponentManagerConfig :members: :undoc-members: 4. TmcComponentManagerConfig -------------------------------- .. autoclass:: ska_tmc_common.v4.ska_device_config.TmcComponentManagerConfig :members: :undoc-members: 5. TmcLeafNodeConfig ------------------------ .. autoclass:: ska_tmc_common.v4.ska_device_config.TmcLeafNodeConfig :members: :undoc-members: Guidelines: Adding or Changing Fields --------------------------------------- These dataclasses are constructed by every downstream repository that uses ``ska-tmc-common``, so a field added carelessly here becomes a breaking change several repositories away. Before adding or changing a field: 1. **Put the field in the narrowest class that needs it.** Shared timeouts belong on ``TimeoutConfig``; node-only or leaf-only settings belong on ``TmcComponentManagerConfig`` or ``TmcLeafNodeConfig`` respectively. Don't widen a base class just to save one subclass a line -- it forces every other subclass to carry a field it doesn't use. 2. **Always use** ``@dataclass(kw_only=True)``. Every class in this module is keyword-only. This means adding a new field never shifts the positional meaning of existing fields, so existing call sites that construct a config with keyword arguments keep working unchanged. 3. **Give new fields a default whenever possible.** A field without a default forces every downstream constructor call to be updated immediately. Only leave a field without a default (like ``TelmodelConfig.telmodel_source``) when there genuinely is no safe value to assume. 4. **Never use a mutable default directly.** Use ``field(default_factory=...)`` for anything mutable (``dict``, ``list``, another dataclass instance). A bare ``= []`` or ``= {}`` is shared across every instance of the class. 5. **Watch out for circular imports.** Some fields need to reference types defined in modules that import this one back (e.g. ``TmcComponent``). Keep ``from __future__ import annotations`` at the top of the module and import those types only under ``if TYPE_CHECKING:`` -- the annotation is still valid for type checkers and documentation, but no runtime import cycle is created. 6. **Treat a default-value change like an API change, not a tweak.** Changing an existing field's default (or its type, e.g. an ``int`` timeout becoming a ``float`` to allow sub-second precision) silently changes behaviour for every downstream repository that doesn't override it explicitly. Call this out clearly in the changelog entry rather than folding it into an unrelated commit. 7. **Document units and constraints in the field's docstring or an inline comment.** A dataclass field carries no context of its own -- state explicitly whether a timeout is in seconds, whether ``None`` is a valid value and what it means, etc. 8. **Keep this page and** ``CHANGELOG.rst`` **up to date.** These config classes are part of the public API surface once exported; treat adding, renaming or removing a field the same way you'd treat changing a public method signature.