Docstring Templates for aiohomematic¶
This document provides ready-to-use docstring templates for common patterns in the aiohomematic codebase. Copy and adapt these templates when writing new code.
Related Documents:
- Docstring Standards - Complete style guide
Module Docstrings¶
Template: Tier 1 (Core API Modules)¶
"""
{Brief one-line description ending with period}.
Overview
--------
{2-3 paragraphs explaining:
- Purpose and responsibilities
- Key design decisions
- How it fits into the architecture}
{Optional section: Architecture/Subpackages/Components}
-----------------
{Bulleted list or paragraphs describing major components}
Public API
----------
- `ClassName`: Brief description.
- `function_name`: Brief description.
Quick start
-----------
{Short code example showing typical usage:}
from aiohomematic.{package} import SomeClass
instance = SomeClass(param1="value", param2=42)
result = await instance.do_something()
Notes
-----
{Optional additional information, warnings, or references}
"""
Use for: aiohomematic/__init__.py, central/__init__.py, client/__init__.py, model/__init__.py, model/hub/__init__.py
Template: Tier 2 (Coordinator/Internal Modules)¶
"""
{Brief one-line description ending with period}.
{1-2 paragraphs providing context and explaining key responsibilities}
Key features:
- Feature or responsibility 1
- Feature or responsibility 2
- Feature or responsibility 3
"""
Use for: Coordinators, store modules, internal implementations
Example:
"""
Device coordinator for managing device lifecycle and operations.
This module provides centralized device management including device creation,
registration, removal, and device-related operations. The DeviceCoordinator
works in conjunction with DeviceRegistry to maintain the runtime device model.
Key features:
- Device creation from descriptions
- Device registration and lookup
- Device removal and cleanup
- Device update operations
"""
Template: Tier 3 (Utility/Generic Modules)¶
Use for: Utilities, constants, generic implementations, simple modules
Examples:
"""
Constants and enumerations for aiohomematic.
Public API of this module is defined by __all__.
"""
"""
Generic sensor data points for numeric and text values.
Public API of this module is defined by __all__.
"""
Class Docstrings¶
Template: Protocol/Interface¶
Examples:
class DeviceProvider(Protocol):
"""Protocol for providing access to device registry."""
class CentralInfo(Protocol):
"""Protocol for central system information."""
class TaskScheduler(Protocol):
"""Protocol for scheduling background tasks."""
Template: Base Class¶
class BaseClassName(ABC):
"""
Base class for {purpose}.
{Optional: Explain inheritance contract and what subclasses must implement}
"""
Examples:
class BaseDataPoint(ABC):
"""
Base class for all data point implementations.
Subclasses must implement value property and update methods.
"""
class CustomDataPoint(BaseDataPoint):
"""Base class for custom device-specific data points."""
Template: Concrete Class (Single Line)¶
Examples:
class Device:
"""Represents a Homematic device with channels and data points."""
class Channel:
"""Represents a device channel containing data points."""
class SchedulerJob:
"""Scheduled background task with interval-based execution."""
Template: Data Class¶
Examples:
@dataclass
class CentralConfig:
"""Configuration for central unit initialization."""
@dataclass
class InterfaceConfig:
"""Configuration for a single interface connection."""
Method and Function Docstrings¶
Template: Simple Method (One-Line)¶
Examples:
def get_device_by_address(self, address: str) -> Device | None:
"""Return device by address."""
def is_connected(self) -> bool:
"""Return connection status."""
def clear_cache(self) -> None:
"""Clear all cached data."""
Template: Property¶
Examples:
@property
def device_address(self) -> str:
"""Return the device address."""
@property
def available(self) -> bool:
"""Return whether device is available."""
@config_property
def value(self) -> Any:
"""Return current data point value."""
Template: Complex Method with Args/Returns¶
def method_name(
self,
*,
param1: Type1,
param2: Type2,
optional_param: Type3 = default,
) -> ReturnType:
"""
{Brief description of what the method does}.
Args:
param1: Description of param1
param2: Description of param2
optional_param: Description of optional parameter
Returns:
Description of return value.
Raises:
ExceptionType: When this exception occurs.
"""
Examples:
def create_device(
self,
*,
interface_id: str,
device_address: str,
device_type: str,
force_create: bool = False,
) -> Device:
"""
Create and register a new device instance.
Args:
interface_id: Interface identifier (e.g., "hmip-rf")
device_address: Unique device address
device_type: Device type identifier
force_create: Force creation even if device exists
Returns:
Created or existing Device instance.
Raises:
DeviceCreationException: If device creation fails.
"""
Template: Simple init Method¶
Examples:
def __init__(self) -> None:
"""Initialize the coordinator."""
def __init__(self) -> None:
"""Initialize the event bus."""
Template: Complex init Method¶
def __init__(
self,
*,
param1: Type1,
param2: Type2,
param3: Type3,
) -> None:
"""
Initialize the {class name}.
Args:
param1: Description of param1
param2: Description of param2
param3: Description of param3
"""
Examples:
def __init__(
self,
*,
central_info: CentralInfo,
device_provider: DeviceProvider,
client_provider: ClientProvider,
) -> None:
"""
Initialize the device coordinator.
Args:
central_info: System information provider
device_provider: Device registry access
client_provider: Client lookup functionality
"""
Template: Validator Function¶
Examples:
def channel_address(value: str, /) -> str:
"""Validate channel address format."""
def positive_int(value: int, /) -> int:
"""Validate value is positive integer."""
def interface_id(value: str, /) -> str:
"""Validate interface identifier."""
Template: Decorator¶
def decorator_name[**P, R](
func: Callable[P, R] | None = None,
/,
*,
param1: Type1 = default1,
param2: Type2 = default2,
) -> DecoratorReturnType:
"""
{Brief description of decorator purpose}.
{Explanation of behavior and usage patterns}
Can be used with or without parameters:
@decorator_name
@decorator_name(param1=value)
Args:
func: Function to decorate (when used without parameters)
param1: Description of param1
param2: Description of param2
Returns:
Decorated function or decorator function.
"""
Example:
def inspector[**P, R](
func: Callable[P, R] | None = None,
/,
*,
log_level: int = logging.ERROR,
re_raise: bool = True,
scope: ServiceScope = ServiceScope.EXTERNAL,
) -> Callable[[Callable[P, R]], Callable[P, R]] | Callable[P, R]:
"""
Decorator for exception handling and performance measurement.
Works with both sync and async functions. Can be used with or without
parameters:
@inspector
@inspector(log_level=logging.DEBUG)
@inspector(re_raise=False, service=ServiceScope.INTERNAL)
Args:
func: Function to decorate (when used without parameters)
log_level: Logging level for exceptions
re_raise: Whether to re-raise caught exceptions
scope: The scope of this service method (see ServiceScope enum).
EXTERNAL: Methods for external consumers (HA) - user-invokable commands
like turn_on, turn_off. Appears in service_method_names.
INTERNAL: Infrastructure methods like load_data_point_value.
Does NOT appear in service_method_names.
Returns:
Decorated function or decorator function.
"""
Test Docstrings¶
Template: Test Module¶
Examples:
"""Tests for device coordinator functionality."""
"""Tests for custom climate data points."""
"""Tests for central unit lifecycle."""
Template: Test Class¶
Examples:
class TestDeviceCoordinator:
"""Test suite for DeviceCoordinator."""
class TestCentralUnit:
"""Test suite for CentralUnit lifecycle."""
Template: Test Function¶
Examples:
async def test_device_creation(factory):
"""Test device creation with valid parameters."""
def test_address_validation():
"""Test address validation with various inputs."""
async def test_connection_error_handling(central):
"""Test central handles connection errors gracefully."""
Custom Data Point Docstrings¶
Template: Custom Entity Class¶
Examples:
class CeClimate(CustomDataPoint):
"""Custom entity for thermostat and climate devices."""
class CeCover(CustomDataPoint):
"""Custom entity for blinds and shutters."""
class CeLight(CustomDataPoint):
"""Custom entity for dimmable and colored lights."""
Calculated Data Point Docstrings¶
Template: Calculated Entity¶
class CalculatedEntityName(CalculatedDataPoint):
"""Calculated data point for {what is calculated}."""
Examples:
class DewPoint(CalculatedDataPoint):
"""Calculated data point for dew point temperature."""
class OperatingVoltageLevel(CalculatedDataPoint):
"""Calculated data point for battery level percentage."""
Quick Reference: Verb Usage¶
| Action | Verb | Example |
|---|---|---|
| Retrieving | Return | """Return the device address.""" |
| Creating | Initialize, Create | """Initialize the central unit.""" |
| Validating | Validate | """Validate channel address format.""" |
| Checking | Check | """Check if device is ready.""" |
| Converting | Convert | """Convert value to integer.""" |
| Starting | Start | """Start the background scheduler.""" |
| Stopping | Stop | """Stop all running tasks.""" |
| Registering | Register | """Register device in registry.""" |
| Removing | Remove | """Remove device from registry.""" |
Avoid: "Get", "Fetch", "Retrieve" - use "Return" instead for consistency.
Anti-Patterns to Avoid¶
❌ Repeating Type Information¶
# Bad
def get_address(self) -> str:
"""Return the address as a string."""
# Good
def get_address(self) -> str:
"""Return the device address."""
❌ Vague Docstrings¶
# Bad
def process_data(self, data: dict[str, Any]) -> None:
"""Process the data."""
# Good
def process_data(self, data: dict[str, Any]) -> None:
"""Update device state from backend data."""
❌ Inconsistent Verbs¶
# Bad - Mixed verbs
def get_device(self, address: str) -> Device:
"""Gets device."""
def fetch_channels(self) -> list[Channel]:
"""Fetches channels."""
# Good - Consistent imperative mood
def get_device(self, address: str) -> Device:
"""Return device by address."""
def fetch_channels(self) -> list[Channel]:
"""Return all device channels."""
❌ Missing Periods¶
# Bad
def clear_cache(self) -> None:
"""Clear the cache"""
# Good
def clear_cache(self) -> None:
"""Clear the cache."""
Last Updated: 2025-11-24 Version: 1.0