Skip to content

no-service-behavior-in-settings

Settings and configuration types should not orchestrate injected collaborators.

Why

A class named as settings or configuration promises passive data. Calling injected stores, clients, or services from that object hides orchestration behind a data boundary and couples configuration construction to runtime behavior.

Fix

Move collaborator calls into a service, coordinator, or compiler with an honest behavioral name; keep the settings/configuration object as a TypedDict, Pydantic model, attrs class, or dataclass.

Examples

Before — flagged A settings-named class calls injected persistence
app/batch_settings.py
class BatchSettings:
def __init__(self, store: ScheduleStore) -> None:
self._store = store
async def repoint(self, batch_id: str) -> int:
return await self._store.repoint(batch_id)
After — preferred A settings type remains a passive record
app/batch_settings.py
from dataclasses import dataclass
@dataclass(frozen=True, slots=True)
class BatchSettings:
retry_limit: int