Repository: home-assistant/core
File: homeassistant/components/calendar/__init__.py (Python)

Code before:
    return (summary, datetime.timedelta())


def is_offset_reached(
    start: datetime.datetime, offset_time: datetime.timedelta
) -> bool:
    """Have we reached the offset time specified in the event title."""
    if offset_time == datetime.timedelta():
        return False
    return start + offset_time <= dt_util.now(start.tzinfo)


class CalendarEntityDescription(EntityDescription, frozen_or_thawed=True):
    """A class that describes calendar entities."""


class CalendarEntity(Entity):
    """Base class for calendar event entities."""

    entity_description: CalendarEntityDescription

    _entity_component_unrecorded_attributes = frozenset({"description"})

    _alarm_unsubs: list[CALLBACK_TYPE] | None = None

    _attr_initial_color: str | None = None

    def get_initial_entity_options(self) -> er.EntityOptionsType | None:
        """Return initial entity options."""
        if self._attr_initial_color is None:
            return None

        # Validate that it's a valid hex color string with # prefix
        try:
            validated_color = cv.color_hex(self._attr_initial_color)
        except vol.Invalid:
            return None

        return {DOMAIN: {"color": validated_color}}

    @property
    def event(self) -> CalendarEvent | None:
        """Return the next upcoming event."""
        raise NotImplementedError

    @final
    @property
    def state_attributes(self) -> dict[str, Any] | None:
        """Return the entity state attributes."""
        if (event := self.event) is None:
            return None

Review comment (suggestion):
I think the common pattern is to have both the raw attribute `_attr_initial_color` and a property method that is used by default:

```
@property
def initial_color(self) -> str:
    ....
    return _attr_initial_color
```

Code after:
    return (summary, datetime.timedelta())


def is_offset_reached(
    start: datetime.datetime, offset_time: datetime.timedelta
) -> bool:
    """Have we reached the offset time specified in the event title."""
    if offset_time == datetime.timedelta():
        return False
    return start + offset_time <= dt_util.now(start.tzinfo)


class CalendarEntityDescription(EntityDescription, frozen_or_thawed=True):
    """A class that describes calendar entities."""


class CalendarEntity(Entity):
    """Base class for calendar event entities."""

    entity_description: CalendarEntityDescription

    _entity_component_unrecorded_attributes = frozenset({"description"})

    _alarm_unsubs: list[CALLBACK_TYPE] | None = None

    _attr_initial_color: str | None = None

    @property
    def initial_color(self) -> str | None:
        """Return the initial color for the calendar entity."""
        return self._attr_initial_color

    def get_initial_entity_options(self) -> er.EntityOptionsType | None:
        """Return initial entity options."""
        if self.initial_color is None:
            return None

        # Validate that it's a valid hex color string with # prefix
        try:
            validated_color = cv.color_hex(self.initial_color)
        except vol.Invalid:
            return None

        return {DOMAIN: {"color": validated_color}}

    @property
    def event(self) -> CalendarEvent | None:
        """Return the next upcoming event."""
        raise NotImplementedError

    @final