diff --git a/homeassistant/auth/models.py b/homeassistant/auth/models.py index 2e5f5940544..9242c6a67c6 100644 --- a/homeassistant/auth/models.py +++ b/homeassistant/auth/models.py @@ -3,8 +3,9 @@ from __future__ import annotations from datetime import datetime, timedelta +from functools import cached_property import secrets -from typing import TYPE_CHECKING, Any, NamedTuple +from typing import Any, NamedTuple import uuid import attr @@ -18,12 +19,6 @@ from homeassistant.util import dt as dt_util from . import permissions as perm_mdl from .const import GROUP_ID_ADMIN -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - - TOKEN_TYPE_NORMAL = "normal" TOKEN_TYPE_SYSTEM = "system" TOKEN_TYPE_LONG_LIVED_ACCESS_TOKEN = "long_lived_access_token" diff --git a/homeassistant/backports/functools.py b/homeassistant/backports/functools.py index 8aab50eeb66..96c9888bd80 100644 --- a/homeassistant/backports/functools.py +++ b/homeassistant/backports/functools.py @@ -1,79 +1,16 @@ -"""Functools backports from standard lib.""" +"""Functools backports from standard lib. -# This file contains parts of Python's module wrapper -# for the _functools C module -# to allow utilities written in Python to be added -# to the functools module. -# Written by Nick Coghlan , -# Raymond Hettinger , -# and Łukasz Langa . -# Copyright © 2001-2023 Python Software Foundation; All Rights Reserved +This file contained the backport of the cached_property implementation of Python 3.12. + +Since we have dropped support for Python 3.11, we can remove this backport. +This file is kept for now to avoid breaking custom components that might +import it. +""" from __future__ import annotations -from collections.abc import Callable -from types import GenericAlias -from typing import Any, Generic, Self, TypeVar, overload +from functools import cached_property -_T = TypeVar("_T") - - -class cached_property(Generic[_T]): - """Backport of Python 3.12's cached_property. - - Includes https://github.com/python/cpython/pull/101890/files - """ - - def __init__(self, func: Callable[[Any], _T]) -> None: - """Initialize.""" - self.func: Callable[[Any], _T] = func - self.attrname: str | None = None - self.__doc__ = func.__doc__ - - def __set_name__(self, owner: type[Any], name: str) -> None: - """Set name.""" - if self.attrname is None: - self.attrname = name - elif name != self.attrname: - raise TypeError( - "Cannot assign the same cached_property to two different names " - f"({self.attrname!r} and {name!r})." - ) - - @overload - def __get__(self, instance: None, owner: type[Any] | None = None) -> Self: ... - - @overload - def __get__(self, instance: Any, owner: type[Any] | None = None) -> _T: ... - - def __get__( - self, instance: Any | None, owner: type[Any] | None = None - ) -> _T | Self: - """Get.""" - if instance is None: - return self - if self.attrname is None: - raise TypeError( - "Cannot use cached_property instance without calling __set_name__ on it." - ) - try: - cache = instance.__dict__ - # not all objects have __dict__ (e.g. class defines slots) - except AttributeError: - msg = ( - f"No '__dict__' attribute on {type(instance).__name__!r} " - f"instance to cache {self.attrname!r} property." - ) - raise TypeError(msg) from None - val = self.func(instance) - try: - cache[self.attrname] = val - except TypeError: - msg = ( - f"The '__dict__' attribute on {type(instance).__name__!r} instance " - f"does not support item assignment for caching {self.attrname!r} property." - ) - raise TypeError(msg) from None - return val - - __class_getitem__ = classmethod(GenericAlias) # type: ignore[var-annotated] +__all__ = [ + "cached_property", +] diff --git a/homeassistant/components/alarm_control_panel/__init__.py b/homeassistant/components/alarm_control_panel/__init__.py index 63c095ea6ce..3260454826a 100644 --- a/homeassistant/components/alarm_control_panel/__init__.py +++ b/homeassistant/components/alarm_control_panel/__init__.py @@ -3,9 +3,9 @@ from __future__ import annotations from datetime import timedelta -from functools import partial +from functools import cached_property, partial import logging -from typing import TYPE_CHECKING, Any, Final, final +from typing import Any, Final, final import voluptuous as vol @@ -50,11 +50,6 @@ from .const import ( # noqa: F401 CodeFormat, ) -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - _LOGGER: Final = logging.getLogger(__name__) SCAN_INTERVAL: Final = timedelta(seconds=30) diff --git a/homeassistant/components/automation/__init__.py b/homeassistant/components/automation/__init__.py index 0bd2ed87d20..ff0a5fc5193 100644 --- a/homeassistant/components/automation/__init__.py +++ b/homeassistant/components/automation/__init__.py @@ -6,9 +6,9 @@ from abc import ABC, abstractmethod import asyncio from collections.abc import Callable, Mapping from dataclasses import dataclass -from functools import partial +from functools import cached_property, partial import logging -from typing import TYPE_CHECKING, Any, Protocol, cast +from typing import Any, Protocol, cast import voluptuous as vol @@ -112,12 +112,6 @@ from .const import ( from .helpers import async_get_blueprints from .trace import trace_automation -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - - ENTITY_ID_FORMAT = DOMAIN + ".{}" diff --git a/homeassistant/components/binary_sensor/__init__.py b/homeassistant/components/binary_sensor/__init__.py index 4fd99c309bc..dad398e2525 100644 --- a/homeassistant/components/binary_sensor/__init__.py +++ b/homeassistant/components/binary_sensor/__init__.py @@ -4,9 +4,9 @@ from __future__ import annotations from datetime import timedelta from enum import StrEnum -from functools import partial +from functools import cached_property, partial import logging -from typing import TYPE_CHECKING, Literal, final +from typing import Literal, final import voluptuous as vol @@ -28,11 +28,6 @@ from homeassistant.helpers.entity import Entity, EntityDescription from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.typing import ConfigType -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/button/__init__.py b/homeassistant/components/button/__init__.py index 10589aa461f..cb8ac7745b2 100644 --- a/homeassistant/components/button/__init__.py +++ b/homeassistant/components/button/__init__.py @@ -4,8 +4,9 @@ from __future__ import annotations from datetime import timedelta from enum import StrEnum +from functools import cached_property import logging -from typing import TYPE_CHECKING, final +from typing import final import voluptuous as vol @@ -24,11 +25,6 @@ from homeassistant.util import dt as dt_util from .const import DOMAIN, SERVICE_PRESS -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - SCAN_INTERVAL = timedelta(seconds=30) ENTITY_ID_FORMAT = DOMAIN + ".{}" diff --git a/homeassistant/components/camera/__init__.py b/homeassistant/components/camera/__init__.py index bfeab601352..a81711f2793 100644 --- a/homeassistant/components/camera/__init__.py +++ b/homeassistant/components/camera/__init__.py @@ -9,12 +9,12 @@ from contextlib import suppress from dataclasses import asdict from datetime import datetime, timedelta from enum import IntFlag -from functools import partial +from functools import cached_property, partial import logging import os from random import SystemRandom import time -from typing import TYPE_CHECKING, Any, Final, cast, final +from typing import Any, Final, cast, final from aiohttp import hdrs, web import attr @@ -85,11 +85,6 @@ from .const import ( # noqa: F401 from .img_util import scale_jpeg_camera_image from .prefs import CameraPreferences, DynamicStreamSettings # noqa: F401 -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - _LOGGER = logging.getLogger(__name__) SERVICE_ENABLE_MOTION: Final = "enable_motion_detection" diff --git a/homeassistant/components/climate/__init__.py b/homeassistant/components/climate/__init__.py index 00fd69ce63b..bda00c9b57f 100644 --- a/homeassistant/components/climate/__init__.py +++ b/homeassistant/components/climate/__init__.py @@ -5,8 +5,9 @@ from __future__ import annotations import asyncio from datetime import timedelta import functools as ft +from functools import cached_property import logging -from typing import TYPE_CHECKING, Any, Literal, final +from typing import Any, Literal, final import voluptuous as vol @@ -117,11 +118,6 @@ from .const import ( # noqa: F401 HVACMode, ) -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - DEFAULT_MIN_TEMP = 7 DEFAULT_MAX_TEMP = 35 DEFAULT_MIN_HUMIDITY = 30 diff --git a/homeassistant/components/cover/__init__.py b/homeassistant/components/cover/__init__.py index 1eac6844703..71e89797c05 100644 --- a/homeassistant/components/cover/__init__.py +++ b/homeassistant/components/cover/__init__.py @@ -6,8 +6,9 @@ from collections.abc import Callable from datetime import timedelta from enum import IntFlag, StrEnum import functools as ft +from functools import cached_property import logging -from typing import TYPE_CHECKING, Any, ParamSpec, TypeVar, final +from typing import Any, ParamSpec, TypeVar, final import voluptuous as vol @@ -46,11 +47,6 @@ from homeassistant.loader import bind_hass from . import group as group_pre_import # noqa: F401 -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - _LOGGER = logging.getLogger(__name__) DOMAIN = "cover" diff --git a/homeassistant/components/date/__init__.py b/homeassistant/components/date/__init__.py index 3cb6ad3a77d..ddd85ffbf06 100644 --- a/homeassistant/components/date/__init__.py +++ b/homeassistant/components/date/__init__.py @@ -3,8 +3,9 @@ from __future__ import annotations from datetime import date, timedelta +from functools import cached_property import logging -from typing import TYPE_CHECKING, final +from typing import final import voluptuous as vol @@ -22,12 +23,6 @@ from homeassistant.helpers.typing import ConfigType from .const import DOMAIN, SERVICE_SET_VALUE -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - - SCAN_INTERVAL = timedelta(seconds=30) ENTITY_ID_FORMAT = DOMAIN + ".{}" diff --git a/homeassistant/components/datetime/__init__.py b/homeassistant/components/datetime/__init__.py index 420cf27b5aa..b1be0a0d08d 100644 --- a/homeassistant/components/datetime/__init__.py +++ b/homeassistant/components/datetime/__init__.py @@ -3,8 +3,9 @@ from __future__ import annotations from datetime import UTC, datetime, timedelta +from functools import cached_property import logging -from typing import TYPE_CHECKING, final +from typing import final import voluptuous as vol @@ -22,11 +23,6 @@ from homeassistant.util import dt as dt_util from .const import ATTR_DATETIME, DOMAIN, SERVICE_SET_VALUE -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - SCAN_INTERVAL = timedelta(seconds=30) ENTITY_ID_FORMAT = DOMAIN + ".{}" diff --git a/homeassistant/components/device_tracker/legacy.py b/homeassistant/components/device_tracker/legacy.py index 47751bf5e90..1d1d4645bb4 100644 --- a/homeassistant/components/device_tracker/legacy.py +++ b/homeassistant/components/device_tracker/legacy.py @@ -5,6 +5,7 @@ from __future__ import annotations import asyncio from collections.abc import Callable, Coroutine, Sequence from datetime import datetime, timedelta +from functools import cached_property import hashlib from types import ModuleType from typing import Any, Final, Protocol, final @@ -13,7 +14,6 @@ import attr import voluptuous as vol from homeassistant import util -from homeassistant.backports.functools import cached_property from homeassistant.components import zone from homeassistant.components.zone import ENTITY_ID_HOME from homeassistant.config import ( diff --git a/homeassistant/components/dlna_dms/dms.py b/homeassistant/components/dlna_dms/dms.py index aaa55e3ad3e..66c328f2e92 100644 --- a/homeassistant/components/dlna_dms/dms.py +++ b/homeassistant/components/dlna_dms/dms.py @@ -7,6 +7,7 @@ from collections.abc import Callable, Coroutine from dataclasses import dataclass from enum import StrEnum import functools +from functools import cached_property from typing import Any, TypeVar, cast from async_upnp_client.aiohttp import AiohttpSessionRequester @@ -17,7 +18,6 @@ from async_upnp_client.exceptions import UpnpActionError, UpnpConnectionError, U from async_upnp_client.profiles.dlna import ContentDirectoryErrorCode, DmsDevice from didl_lite import didl_lite -from homeassistant.backports.functools import cached_property from homeassistant.components import ssdp from homeassistant.components.media_player import BrowseError, MediaClass from homeassistant.components.media_source.error import Unresolvable diff --git a/homeassistant/components/event/__init__.py b/homeassistant/components/event/__init__.py index 2ad0e6d950b..925c0855c71 100644 --- a/homeassistant/components/event/__init__.py +++ b/homeassistant/components/event/__init__.py @@ -5,8 +5,9 @@ from __future__ import annotations from dataclasses import asdict, dataclass from datetime import datetime, timedelta from enum import StrEnum +from functools import cached_property import logging -from typing import TYPE_CHECKING, Any, Self, final +from typing import Any, Self, final from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant @@ -22,12 +23,6 @@ from homeassistant.util import dt as dt_util from .const import ATTR_EVENT_TYPE, ATTR_EVENT_TYPES, DOMAIN -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - - SCAN_INTERVAL = timedelta(seconds=30) ENTITY_ID_FORMAT = DOMAIN + ".{}" diff --git a/homeassistant/components/fan/__init__.py b/homeassistant/components/fan/__init__.py index b62f207bde8..0bed3eb1ff2 100644 --- a/homeassistant/components/fan/__init__.py +++ b/homeassistant/components/fan/__init__.py @@ -5,9 +5,10 @@ from __future__ import annotations from datetime import timedelta from enum import IntFlag import functools as ft +from functools import cached_property import logging import math -from typing import TYPE_CHECKING, Any, final +from typing import Any, final import voluptuous as vol @@ -40,12 +41,6 @@ from homeassistant.util.percentage import ( ranged_value_to_percentage, ) -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - - _LOGGER = logging.getLogger(__name__) DOMAIN = "fan" diff --git a/homeassistant/components/ffmpeg/__init__.py b/homeassistant/components/ffmpeg/__init__.py index b4c919fcb79..09d8e2401f0 100644 --- a/homeassistant/components/ffmpeg/__init__.py +++ b/homeassistant/components/ffmpeg/__init__.py @@ -3,8 +3,9 @@ from __future__ import annotations import asyncio +from functools import cached_property import re -from typing import TYPE_CHECKING, Generic, TypeVar +from typing import Generic, TypeVar from haffmpeg.core import HAFFmpeg from haffmpeg.tools import IMAGE_JPEG, FFVersion, ImageFrame @@ -28,12 +29,6 @@ from homeassistant.helpers.typing import ConfigType from homeassistant.loader import bind_hass from homeassistant.util.signal_type import SignalType -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - - _HAFFmpegT = TypeVar("_HAFFmpegT", bound=HAFFmpeg) DOMAIN = "ffmpeg" diff --git a/homeassistant/components/fints/sensor.py b/homeassistant/components/fints/sensor.py index 6d3f1f63b84..4a4c2d05181 100644 --- a/homeassistant/components/fints/sensor.py +++ b/homeassistant/components/fints/sensor.py @@ -4,6 +4,7 @@ from __future__ import annotations from collections import namedtuple from datetime import timedelta +from functools import cached_property import logging from typing import Any @@ -11,7 +12,6 @@ from fints.client import FinTS3PinTanClient from fints.models import SEPAAccount import voluptuous as vol -from homeassistant.backports.functools import cached_property from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity from homeassistant.const import CONF_NAME, CONF_PIN, CONF_URL, CONF_USERNAME from homeassistant.core import HomeAssistant diff --git a/homeassistant/components/geo_location/__init__.py b/homeassistant/components/geo_location/__init__.py index d81fab65dc9..48e2f35ccc1 100644 --- a/homeassistant/components/geo_location/__init__.py +++ b/homeassistant/components/geo_location/__init__.py @@ -3,8 +3,9 @@ from __future__ import annotations from datetime import timedelta +from functools import cached_property import logging -from typing import TYPE_CHECKING, Any, final +from typing import Any, final from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_LATITUDE, ATTR_LONGITUDE @@ -17,12 +18,6 @@ from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.typing import ConfigType -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - - _LOGGER = logging.getLogger(__name__) ATTR_DISTANCE = "distance" diff --git a/homeassistant/components/homekit_controller/climate.py b/homeassistant/components/homekit_controller/climate.py index 49ae3bb4a42..544e23798d0 100644 --- a/homeassistant/components/homekit_controller/climate.py +++ b/homeassistant/components/homekit_controller/climate.py @@ -2,8 +2,9 @@ from __future__ import annotations +from functools import cached_property import logging -from typing import TYPE_CHECKING, Any, Final +from typing import Any, Final from aiohomekit.model.characteristics import ( ActivationStateValues, @@ -49,12 +50,6 @@ from . import KNOWN_DEVICES from .connection import HKDevice from .entity import HomeKitEntity -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - - _LOGGER = logging.getLogger(__name__) # Map of Homekit operation modes to hass modes diff --git a/homeassistant/components/homekit_controller/cover.py b/homeassistant/components/homekit_controller/cover.py index b15ce645a29..ca041d49e11 100644 --- a/homeassistant/components/homekit_controller/cover.py +++ b/homeassistant/components/homekit_controller/cover.py @@ -2,7 +2,8 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any +from functools import cached_property +from typing import Any from aiohomekit.model.characteristics import CharacteristicsTypes from aiohomekit.model.services import Service, ServicesTypes @@ -29,12 +30,6 @@ from . import KNOWN_DEVICES from .connection import HKDevice from .entity import HomeKitEntity -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - - STATE_STOPPED = "stopped" CURRENT_GARAGE_STATE_MAP = { diff --git a/homeassistant/components/homekit_controller/fan.py b/homeassistant/components/homekit_controller/fan.py index 39df2b7ce51..79e302ace74 100644 --- a/homeassistant/components/homekit_controller/fan.py +++ b/homeassistant/components/homekit_controller/fan.py @@ -2,7 +2,8 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any +from functools import cached_property +from typing import Any from aiohomekit.model.characteristics import CharacteristicsTypes from aiohomekit.model.services import Service, ServicesTypes @@ -26,12 +27,6 @@ from . import KNOWN_DEVICES from .connection import HKDevice from .entity import HomeKitEntity -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - - # 0 is clockwise, 1 is counter-clockwise. The match to forward and reverse is so that # its consistent with homeassistant.components.homekit. DIRECTION_TO_HK = { diff --git a/homeassistant/components/homekit_controller/humidifier.py b/homeassistant/components/homekit_controller/humidifier.py index fecba147a71..cbfcfb6d3bb 100644 --- a/homeassistant/components/homekit_controller/humidifier.py +++ b/homeassistant/components/homekit_controller/humidifier.py @@ -2,7 +2,8 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any +from functools import cached_property +from typing import Any from aiohomekit.model.characteristics import CharacteristicsTypes from aiohomekit.model.services import Service, ServicesTypes @@ -26,12 +27,6 @@ from . import KNOWN_DEVICES from .connection import HKDevice from .entity import HomeKitEntity -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - - HK_MODE_TO_HA = { 0: "off", 1: MODE_AUTO, diff --git a/homeassistant/components/homekit_controller/light.py b/homeassistant/components/homekit_controller/light.py index b314ffe85de..d5f20723ff1 100644 --- a/homeassistant/components/homekit_controller/light.py +++ b/homeassistant/components/homekit_controller/light.py @@ -2,7 +2,8 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any +from functools import cached_property +from typing import Any from aiohomekit.model.characteristics import CharacteristicsTypes from aiohomekit.model.services import Service, ServicesTypes @@ -24,11 +25,6 @@ from . import KNOWN_DEVICES from .connection import HKDevice from .entity import HomeKitEntity -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - async def async_setup_entry( hass: HomeAssistant, diff --git a/homeassistant/components/humidifier/__init__.py b/homeassistant/components/humidifier/__init__.py index 1af294d8640..da79df6d52f 100644 --- a/homeassistant/components/humidifier/__init__.py +++ b/homeassistant/components/humidifier/__init__.py @@ -4,9 +4,9 @@ from __future__ import annotations from datetime import timedelta from enum import StrEnum -from functools import partial +from functools import cached_property, partial import logging -from typing import TYPE_CHECKING, Any, final +from typing import Any, final import voluptuous as vol @@ -56,12 +56,6 @@ from .const import ( # noqa: F401 HumidifierEntityFeature, ) -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - - _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/image/__init__.py b/homeassistant/components/image/__init__.py index 56dc7cc2cfa..59e5ddceebf 100644 --- a/homeassistant/components/image/__init__.py +++ b/homeassistant/components/image/__init__.py @@ -7,9 +7,10 @@ import collections from contextlib import suppress from dataclasses import dataclass from datetime import datetime, timedelta +from functools import cached_property import logging from random import SystemRandom -from typing import TYPE_CHECKING, Final, final +from typing import Final, final from aiohttp import hdrs, web import httpx @@ -35,12 +36,6 @@ from homeassistant.helpers.typing import UNDEFINED, ConfigType, UndefinedType from .const import DOMAIN, IMAGE_TIMEOUT -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - - _LOGGER = logging.getLogger(__name__) SCAN_INTERVAL: Final = timedelta(seconds=30) diff --git a/homeassistant/components/lawn_mower/__init__.py b/homeassistant/components/lawn_mower/__init__.py index f28bd1308b0..8cb9850bde7 100644 --- a/homeassistant/components/lawn_mower/__init__.py +++ b/homeassistant/components/lawn_mower/__init__.py @@ -3,8 +3,9 @@ from __future__ import annotations from datetime import timedelta +from functools import cached_property import logging -from typing import TYPE_CHECKING, final +from typing import final from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant @@ -25,12 +26,6 @@ from .const import ( LawnMowerEntityFeature, ) -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - - SCAN_INTERVAL = timedelta(seconds=60) _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/light/__init__.py b/homeassistant/components/light/__init__.py index 53c7328ece4..726aef73c01 100644 --- a/homeassistant/components/light/__init__.py +++ b/homeassistant/components/light/__init__.py @@ -7,9 +7,10 @@ import csv import dataclasses from datetime import timedelta from enum import IntFlag, StrEnum +from functools import cached_property import logging import os -from typing import TYPE_CHECKING, Any, Self, cast, final +from typing import Any, Self, cast, final import voluptuous as vol @@ -34,11 +35,6 @@ from homeassistant.helpers.typing import ConfigType from homeassistant.loader import bind_hass import homeassistant.util.color as color_util -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - DOMAIN = "light" SCAN_INTERVAL = timedelta(seconds=30) DATA_PROFILES = "light_profiles" diff --git a/homeassistant/components/lock/__init__.py b/homeassistant/components/lock/__init__.py index b2cd28324cb..10c1526c5bb 100644 --- a/homeassistant/components/lock/__init__.py +++ b/homeassistant/components/lock/__init__.py @@ -5,6 +5,7 @@ from __future__ import annotations from datetime import timedelta from enum import IntFlag import functools as ft +from functools import cached_property import logging import re from typing import TYPE_CHECKING, Any, final @@ -44,11 +45,6 @@ from homeassistant.helpers.typing import ConfigType, StateType from . import group as group_pre_import # noqa: F401 -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - _LOGGER = logging.getLogger(__name__) ATTR_CHANGED_BY = "changed_by" diff --git a/homeassistant/components/logbook/models.py b/homeassistant/components/logbook/models.py index 1073c6b0d3a..9409c59985c 100644 --- a/homeassistant/components/logbook/models.py +++ b/homeassistant/components/logbook/models.py @@ -4,6 +4,7 @@ from __future__ import annotations from collections.abc import Callable, Mapping from dataclasses import dataclass +from functools import cached_property from typing import TYPE_CHECKING, Any, cast from sqlalchemy.engine.row import Row @@ -20,11 +21,6 @@ from homeassistant.core import Context, Event, State, callback from homeassistant.util.json import json_loads from homeassistant.util.ulid import ulid_to_bytes -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - @dataclass(slots=True) class LogbookConfig: diff --git a/homeassistant/components/media_player/__init__.py b/homeassistant/components/media_player/__init__.py index 6535aea3e52..35e1b1cb71e 100644 --- a/homeassistant/components/media_player/__init__.py +++ b/homeassistant/components/media_player/__init__.py @@ -9,12 +9,12 @@ from contextlib import suppress import datetime as dt from enum import StrEnum import functools as ft -from functools import lru_cache +from functools import cached_property, lru_cache import hashlib from http import HTTPStatus import logging import secrets -from typing import TYPE_CHECKING, Any, Final, Required, TypedDict, final +from typing import Any, Final, Required, TypedDict, final from urllib.parse import quote, urlparse from aiohttp import web @@ -134,11 +134,6 @@ from .const import ( # noqa: F401 ) from .errors import BrowseError -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - _LOGGER = logging.getLogger(__name__) ENTITY_ID_FORMAT = DOMAIN + ".{}" diff --git a/homeassistant/components/nibe_heatpump/coordinator.py b/homeassistant/components/nibe_heatpump/coordinator.py index 1711c3d8f2a..a3d37ce0719 100644 --- a/homeassistant/components/nibe_heatpump/coordinator.py +++ b/homeassistant/components/nibe_heatpump/coordinator.py @@ -6,6 +6,7 @@ import asyncio from collections import defaultdict from collections.abc import Callable, Iterable from datetime import date, timedelta +from functools import cached_property from typing import Any, Generic, TypeVar from nibe.coil import Coil, CoilData @@ -13,7 +14,6 @@ from nibe.connection import Connection from nibe.exceptions import CoilNotFoundException, ReadException from nibe.heatpump import HeatPump, Series -from homeassistant.backports.functools import cached_property from homeassistant.config_entries import ConfigEntry from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo diff --git a/homeassistant/components/number/__init__.py b/homeassistant/components/number/__init__.py index d3785e0eae6..e5b307f5e57 100644 --- a/homeassistant/components/number/__init__.py +++ b/homeassistant/components/number/__init__.py @@ -6,6 +6,7 @@ from collections.abc import Callable from contextlib import suppress import dataclasses from datetime import timedelta +from functools import cached_property import logging from math import ceil, floor from typing import TYPE_CHECKING, Any, Self, final @@ -44,11 +45,6 @@ from .const import ( # noqa: F401 ) from .websocket_api import async_setup as async_setup_ws_api -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - _LOGGER = logging.getLogger(__name__) ENTITY_ID_FORMAT = DOMAIN + ".{}" diff --git a/homeassistant/components/recorder/models/state.py b/homeassistant/components/recorder/models/state.py index e1f23f32118..ca70b856d76 100644 --- a/homeassistant/components/recorder/models/state.py +++ b/homeassistant/components/recorder/models/state.py @@ -3,6 +3,7 @@ from __future__ import annotations from datetime import datetime +from functools import cached_property import logging from typing import TYPE_CHECKING, Any @@ -19,11 +20,6 @@ import homeassistant.util.dt as dt_util from .state_attributes import decode_attributes_from_source -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - _LOGGER = logging.getLogger(__name__) EMPTY_CONTEXT = Context(id=None) diff --git a/homeassistant/components/remote/__init__.py b/homeassistant/components/remote/__init__.py index 2b88c51e936..88813e4a70c 100644 --- a/homeassistant/components/remote/__init__.py +++ b/homeassistant/components/remote/__init__.py @@ -6,8 +6,9 @@ from collections.abc import Iterable from datetime import timedelta from enum import IntFlag import functools as ft +from functools import cached_property import logging -from typing import TYPE_CHECKING, Any, final +from typing import Any, final import voluptuous as vol @@ -37,12 +38,6 @@ from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.typing import ConfigType from homeassistant.loader import bind_hass -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - - _LOGGER = logging.getLogger(__name__) ATTR_ACTIVITY = "activity" diff --git a/homeassistant/components/script/__init__.py b/homeassistant/components/script/__init__.py index 82752ed15bc..6aeb0a9965e 100644 --- a/homeassistant/components/script/__init__.py +++ b/homeassistant/components/script/__init__.py @@ -5,8 +5,9 @@ from __future__ import annotations from abc import ABC, abstractmethod import asyncio from dataclasses import dataclass +from functools import cached_property import logging -from typing import TYPE_CHECKING, Any, cast +from typing import Any, cast import voluptuous as vol @@ -74,12 +75,6 @@ from .const import ( from .helpers import async_get_blueprints from .trace import trace_script -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - - SCRIPT_SERVICE_SCHEMA = vol.Schema(dict) SCRIPT_TURN_ONOFF_SCHEMA = make_entity_service_schema( {vol.Optional(ATTR_VARIABLES): {str: cv.match_all}} diff --git a/homeassistant/components/select/__init__.py b/homeassistant/components/select/__init__.py index 0c54dfc0aac..6e134c8958c 100644 --- a/homeassistant/components/select/__init__.py +++ b/homeassistant/components/select/__init__.py @@ -3,8 +3,9 @@ from __future__ import annotations from datetime import timedelta +from functools import cached_property import logging -from typing import TYPE_CHECKING, Any, final +from typing import Any, final import voluptuous as vol @@ -32,11 +33,6 @@ from .const import ( SERVICE_SELECT_PREVIOUS, ) -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - SCAN_INTERVAL = timedelta(seconds=30) ENTITY_ID_FORMAT = DOMAIN + ".{}" diff --git a/homeassistant/components/sensor/__init__.py b/homeassistant/components/sensor/__init__.py index 92499a05af4..1d06e1a24c4 100644 --- a/homeassistant/components/sensor/__init__.py +++ b/homeassistant/components/sensor/__init__.py @@ -8,10 +8,10 @@ from contextlib import suppress from dataclasses import dataclass from datetime import UTC, date, datetime, timedelta from decimal import Decimal, InvalidOperation as DecimalInvalidOperation -from functools import partial +from functools import cached_property, partial import logging from math import ceil, floor, isfinite, log10 -from typing import TYPE_CHECKING, Any, Final, Self, cast, final, override +from typing import Any, Final, Self, cast, final, override from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( # noqa: F401 @@ -91,11 +91,6 @@ from .const import ( # noqa: F401 ) from .websocket_api import async_setup as async_setup_ws_api -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - _LOGGER: Final = logging.getLogger(__name__) ENTITY_ID_FORMAT: Final = DOMAIN + ".{}" diff --git a/homeassistant/components/siren/__init__.py b/homeassistant/components/siren/__init__.py index a083aa9d702..a0a599dd2df 100644 --- a/homeassistant/components/siren/__init__.py +++ b/homeassistant/components/siren/__init__.py @@ -3,9 +3,9 @@ from __future__ import annotations from datetime import timedelta -from functools import partial +from functools import cached_property, partial import logging -from typing import TYPE_CHECKING, Any, TypedDict, cast, final +from typing import Any, TypedDict, cast, final import voluptuous as vol @@ -40,11 +40,6 @@ from .const import ( # noqa: F401 SirenEntityFeature, ) -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - _LOGGER = logging.getLogger(__name__) SCAN_INTERVAL = timedelta(seconds=60) diff --git a/homeassistant/components/switch/__init__.py b/homeassistant/components/switch/__init__.py index 86c67248eea..995bcda294f 100644 --- a/homeassistant/components/switch/__init__.py +++ b/homeassistant/components/switch/__init__.py @@ -4,9 +4,8 @@ from __future__ import annotations from datetime import timedelta from enum import StrEnum -from functools import partial +from functools import cached_property, partial import logging -from typing import TYPE_CHECKING import voluptuous as vol @@ -35,11 +34,6 @@ from homeassistant.loader import bind_hass from .const import DOMAIN -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - SCAN_INTERVAL = timedelta(seconds=30) ENTITY_ID_FORMAT = DOMAIN + ".{}" diff --git a/homeassistant/components/template/template_entity.py b/homeassistant/components/template/template_entity.py index 735fa7ddd23..7f24f31c692 100644 --- a/homeassistant/components/template/template_entity.py +++ b/homeassistant/components/template/template_entity.py @@ -4,9 +4,10 @@ from __future__ import annotations from collections.abc import Callable, Mapping import contextlib +from functools import cached_property import itertools import logging -from typing import TYPE_CHECKING, Any +from typing import Any import voluptuous as vol @@ -58,11 +59,6 @@ from .const import ( CONF_PICTURE, ) -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - _LOGGER = logging.getLogger(__name__) TEMPLATE_ENTITY_AVAILABILITY_SCHEMA = vol.Schema( diff --git a/homeassistant/components/text/__init__.py b/homeassistant/components/text/__init__.py index cf29910cc34..f45a9cf3563 100644 --- a/homeassistant/components/text/__init__.py +++ b/homeassistant/components/text/__init__.py @@ -5,9 +5,10 @@ from __future__ import annotations from dataclasses import asdict, dataclass from datetime import timedelta from enum import StrEnum +from functools import cached_property import logging import re -from typing import TYPE_CHECKING, Any, final +from typing import Any, final import voluptuous as vol @@ -34,11 +35,6 @@ from .const import ( SERVICE_SET_VALUE, ) -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - SCAN_INTERVAL = timedelta(seconds=30) ENTITY_ID_FORMAT = DOMAIN + ".{}" diff --git a/homeassistant/components/thread/dataset_store.py b/homeassistant/components/thread/dataset_store.py index de322510ef2..b880be801a4 100644 --- a/homeassistant/components/thread/dataset_store.py +++ b/homeassistant/components/thread/dataset_store.py @@ -5,13 +5,13 @@ from __future__ import annotations from asyncio import Event, Task, wait import dataclasses from datetime import datetime +from functools import cached_property import logging from typing import Any, cast from python_otbr_api import tlv_parser from python_otbr_api.tlv_parser import MeshcopTLVType -from homeassistant.backports.functools import cached_property from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.singleton import singleton diff --git a/homeassistant/components/time/__init__.py b/homeassistant/components/time/__init__.py index 2e87aaac28d..4e101ddd67d 100644 --- a/homeassistant/components/time/__init__.py +++ b/homeassistant/components/time/__init__.py @@ -3,8 +3,9 @@ from __future__ import annotations from datetime import time, timedelta +from functools import cached_property import logging -from typing import TYPE_CHECKING, final +from typing import final import voluptuous as vol @@ -22,12 +23,6 @@ from homeassistant.helpers.typing import ConfigType from .const import DOMAIN, SERVICE_SET_VALUE -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - - SCAN_INTERVAL = timedelta(seconds=30) ENTITY_ID_FORMAT = DOMAIN + ".{}" diff --git a/homeassistant/components/todo/__init__.py b/homeassistant/components/todo/__init__.py index 74ee99b811f..e574c6372a7 100644 --- a/homeassistant/components/todo/__init__.py +++ b/homeassistant/components/todo/__init__.py @@ -3,8 +3,9 @@ from collections.abc import Callable, Iterable import dataclasses import datetime +from functools import cached_property import logging -from typing import TYPE_CHECKING, Any, final +from typing import Any, final import voluptuous as vol @@ -41,12 +42,6 @@ from .const import ( TodoListEntityFeature, ) -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - - _LOGGER = logging.getLogger(__name__) SCAN_INTERVAL = datetime.timedelta(seconds=60) diff --git a/homeassistant/components/update/__init__.py b/homeassistant/components/update/__init__.py index 142c9b4a6c3..57d63c92ede 100644 --- a/homeassistant/components/update/__init__.py +++ b/homeassistant/components/update/__init__.py @@ -4,9 +4,9 @@ from __future__ import annotations from datetime import timedelta from enum import StrEnum -from functools import lru_cache +from functools import cached_property, lru_cache import logging -from typing import TYPE_CHECKING, Any, Final, final +from typing import Any, Final, final from awesomeversion import AwesomeVersion, AwesomeVersionCompareException import voluptuous as vol @@ -43,11 +43,6 @@ from .const import ( UpdateEntityFeature, ) -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - SCAN_INTERVAL = timedelta(minutes=15) ENTITY_ID_FORMAT: Final = DOMAIN + ".{}" diff --git a/homeassistant/components/vacuum/__init__.py b/homeassistant/components/vacuum/__init__.py index bdf690ed63f..4f5b6066dbd 100644 --- a/homeassistant/components/vacuum/__init__.py +++ b/homeassistant/components/vacuum/__init__.py @@ -5,9 +5,9 @@ from __future__ import annotations from collections.abc import Mapping from datetime import timedelta from enum import IntFlag -from functools import partial +from functools import cached_property, partial import logging -from typing import TYPE_CHECKING, Any +from typing import Any import voluptuous as vol @@ -38,11 +38,6 @@ from homeassistant.loader import bind_hass from . import group as group_pre_import # noqa: F401 from .const import STATE_CLEANING, STATE_DOCKED, STATE_ERROR, STATE_RETURNING -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - _LOGGER = logging.getLogger(__name__) DOMAIN = "vacuum" diff --git a/homeassistant/components/water_heater/__init__.py b/homeassistant/components/water_heater/__init__.py index 167acb85914..ad0149919dc 100644 --- a/homeassistant/components/water_heater/__init__.py +++ b/homeassistant/components/water_heater/__init__.py @@ -6,8 +6,9 @@ from collections.abc import Mapping from datetime import timedelta from enum import IntFlag import functools as ft +from functools import cached_property import logging -from typing import TYPE_CHECKING, Any, final +from typing import Any, final import voluptuous as vol @@ -44,12 +45,6 @@ from homeassistant.util.unit_conversion import TemperatureConverter from . import group as group_pre_import # noqa: F401 -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - - DEFAULT_MIN_TEMP = 110 DEFAULT_MAX_TEMP = 140 diff --git a/homeassistant/components/weather/__init__.py b/homeassistant/components/weather/__init__.py index 404154ade2b..95655f439c9 100644 --- a/homeassistant/components/weather/__init__.py +++ b/homeassistant/components/weather/__init__.py @@ -6,10 +6,9 @@ import abc from collections.abc import Callable, Iterable from contextlib import suppress from datetime import timedelta -from functools import partial +from functools import cached_property, partial import logging from typing import ( - TYPE_CHECKING, Any, Final, Generic, @@ -84,12 +83,6 @@ from .const import ( ) from .websocket_api import async_setup as async_setup_ws_api -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - - _LOGGER = logging.getLogger(__name__) ATTR_CONDITION_CLASS = "condition_class" diff --git a/homeassistant/components/zha/core/cluster_handlers/lighting.py b/homeassistant/components/zha/core/cluster_handlers/lighting.py index f19ad311f9e..bde0fdbb0e7 100644 --- a/homeassistant/components/zha/core/cluster_handlers/lighting.py +++ b/homeassistant/components/zha/core/cluster_handlers/lighting.py @@ -2,9 +2,9 @@ from __future__ import annotations -from zigpy.zcl.clusters.lighting import Ballast, Color +from functools import cached_property -from homeassistant.backports.functools import cached_property +from zigpy.zcl.clusters.lighting import Ballast, Color from .. import registries from ..const import REPORT_CONFIG_DEFAULT diff --git a/homeassistant/components/zha/core/device.py b/homeassistant/components/zha/core/device.py index e5fdfe36a9b..65292e275de 100644 --- a/homeassistant/components/zha/core/device.py +++ b/homeassistant/components/zha/core/device.py @@ -6,6 +6,7 @@ import asyncio from collections.abc import Callable from datetime import timedelta from enum import Enum +from functools import cached_property import logging import random import time @@ -23,7 +24,6 @@ from zigpy.zcl.clusters.general import Groups, Identify from zigpy.zcl.foundation import Status as ZclStatus, ZCLCommandDef import zigpy.zdo.types as zdo_types -from homeassistant.backports.functools import cached_property from homeassistant.const import ATTR_COMMAND, ATTR_DEVICE_ID, ATTR_NAME from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError diff --git a/homeassistant/config_entries.py b/homeassistant/config_entries.py index f92e442e5a3..dbc300891b1 100644 --- a/homeassistant/config_entries.py +++ b/homeassistant/config_entries.py @@ -17,6 +17,7 @@ from contextvars import ContextVar from copy import deepcopy from enum import Enum, StrEnum import functools +from functools import cached_property import logging from random import randint from types import MappingProxyType @@ -69,8 +70,6 @@ from .util.async_ import create_eager_task from .util.decorator import Registry if TYPE_CHECKING: - from functools import cached_property - from .components.bluetooth import BluetoothServiceInfoBleak from .components.dhcp import DhcpServiceInfo from .components.hassio import HassioServiceInfo @@ -78,8 +77,6 @@ if TYPE_CHECKING: from .components.usb import UsbServiceInfo from .components.zeroconf import ZeroconfServiceInfo from .helpers.service_info.mqtt import MqttServiceInfo -else: - from .backports.functools import cached_property _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/core.py b/homeassistant/core.py index 1edeb666492..9a26a971f64 100644 --- a/homeassistant/core.py +++ b/homeassistant/core.py @@ -23,6 +23,7 @@ from dataclasses import dataclass import datetime import enum import functools +from functools import cached_property import inspect import logging import os @@ -116,14 +117,10 @@ from .util.unit_system import ( # Typing imports that create a circular dependency if TYPE_CHECKING: - from functools import cached_property - from .auth import AuthManager from .components.http import ApiConfig, HomeAssistantHTTP from .config_entries import ConfigEntries from .helpers.entity import StateInfo -else: - from .backports.functools import cached_property STOPPING_STAGE_SHUTDOWN_TIMEOUT = 20 STOP_STAGE_SHUTDOWN_TIMEOUT = 100 diff --git a/homeassistant/helpers/device_registry.py b/homeassistant/helpers/device_registry.py index c9a9016560c..8d5fe3f2f94 100644 --- a/homeassistant/helpers/device_registry.py +++ b/homeassistant/helpers/device_registry.py @@ -4,7 +4,7 @@ from __future__ import annotations from collections.abc import Mapping from enum import StrEnum -from functools import lru_cache, partial +from functools import cached_property, lru_cache, partial import logging import time from typing import TYPE_CHECKING, Any, Literal, TypedDict, TypeVar, cast @@ -12,7 +12,6 @@ from typing import TYPE_CHECKING, Any, Literal, TypedDict, TypeVar, cast import attr from yarl import URL -from homeassistant.backports.functools import cached_property from homeassistant.const import EVENT_HOMEASSISTANT_STARTED, EVENT_HOMEASSISTANT_STOP from homeassistant.core import Event, HomeAssistant, callback, get_release_channel from homeassistant.exceptions import HomeAssistantError diff --git a/homeassistant/helpers/entity.py b/homeassistant/helpers/entity.py index 5c8cff2f60b..eee35fa4cca 100644 --- a/homeassistant/helpers/entity.py +++ b/homeassistant/helpers/entity.py @@ -9,6 +9,7 @@ from collections.abc import Callable, Coroutine, Iterable, Mapping, MutableMappi import dataclasses from enum import Enum, IntFlag, auto import functools as ft +from functools import cached_property import logging import math from operator import attrgetter @@ -73,11 +74,7 @@ from .event import ( from .typing import UNDEFINED, StateType, UndefinedType if TYPE_CHECKING: - from functools import cached_property - from .entity_platform import EntityPlatform -else: - from homeassistant.backports.functools import cached_property _T = TypeVar("_T") diff --git a/homeassistant/helpers/entity_registry.py b/homeassistant/helpers/entity_registry.py index 27e73320841..a0e7b669418 100644 --- a/homeassistant/helpers/entity_registry.py +++ b/homeassistant/helpers/entity_registry.py @@ -13,6 +13,7 @@ from __future__ import annotations from collections.abc import Callable, Iterable, KeysView, Mapping from datetime import datetime, timedelta from enum import StrEnum +from functools import cached_property import logging import time from typing import TYPE_CHECKING, Any, Literal, NotRequired, TypedDict, TypeVar, cast @@ -20,7 +21,6 @@ from typing import TYPE_CHECKING, Any, Literal, NotRequired, TypedDict, TypeVar, import attr import voluptuous as vol -from homeassistant.backports.functools import cached_property from homeassistant.const import ( ATTR_DEVICE_CLASS, ATTR_FRIENDLY_NAME, diff --git a/homeassistant/helpers/frame.py b/homeassistant/helpers/frame.py index ee092717753..d86fec3de43 100644 --- a/homeassistant/helpers/frame.py +++ b/homeassistant/helpers/frame.py @@ -7,21 +7,17 @@ from collections.abc import Callable from contextlib import suppress from dataclasses import dataclass import functools +from functools import cached_property import linecache import logging import sys from types import FrameType -from typing import TYPE_CHECKING, Any, TypeVar, cast +from typing import Any, TypeVar, cast from homeassistant.core import HomeAssistant, async_get_hass from homeassistant.exceptions import HomeAssistantError from homeassistant.loader import async_suggest_report_issue -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - _LOGGER = logging.getLogger(__name__) # Keep track of integrations already reported to prevent flooding diff --git a/homeassistant/helpers/script.py b/homeassistant/helpers/script.py index 2ea7b259872..0b054307702 100644 --- a/homeassistant/helpers/script.py +++ b/homeassistant/helpers/script.py @@ -9,11 +9,11 @@ from contextvars import ContextVar from copy import copy from dataclasses import dataclass from datetime import datetime, timedelta -from functools import partial +from functools import cached_property, partial import itertools import logging from types import MappingProxyType -from typing import TYPE_CHECKING, Any, Literal, TypedDict, TypeVar, cast +from typing import Any, Literal, TypedDict, TypeVar, cast import async_interrupt import voluptuous as vol @@ -107,12 +107,6 @@ from .trace import ( from .trigger import async_initialize_triggers, async_validate_trigger_config from .typing import UNDEFINED, ConfigType, UndefinedType -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - - # mypy: allow-untyped-calls, allow-untyped-defs, no-check-untyped-defs _T = TypeVar("_T") diff --git a/homeassistant/helpers/storage.py b/homeassistant/helpers/storage.py index 2413a53e605..c2047328013 100644 --- a/homeassistant/helpers/storage.py +++ b/homeassistant/helpers/storage.py @@ -6,12 +6,13 @@ import asyncio from collections.abc import Callable, Iterable, Mapping, Sequence from contextlib import suppress from copy import deepcopy +from functools import cached_property import inspect from json import JSONDecodeError, JSONEncoder import logging import os from pathlib import Path -from typing import TYPE_CHECKING, Any, Generic, TypeVar +from typing import Any, Generic, TypeVar from homeassistant.const import ( EVENT_HOMEASSISTANT_FINAL_WRITE, @@ -34,12 +35,6 @@ from homeassistant.util.file import WriteError from . import json as json_helper -if TYPE_CHECKING: - from functools import cached_property -else: - from ..backports.functools import cached_property - - # mypy: allow-untyped-calls, allow-untyped-defs, no-warn-return-any # mypy: no-check-untyped-defs MAX_LOAD_CONCURRENTLY = 6 diff --git a/homeassistant/loader.py b/homeassistant/loader.py index eb70f0b83af..da8159ca2cf 100644 --- a/homeassistant/loader.py +++ b/homeassistant/loader.py @@ -11,6 +11,7 @@ from collections.abc import Callable, Iterable from contextlib import suppress from dataclasses import dataclass import functools as ft +from functools import cached_property import importlib import logging import os @@ -41,15 +42,11 @@ from .generated.zeroconf import HOMEKIT, ZEROCONF from .util.json import JSON_DECODE_EXCEPTIONS, json_loads if TYPE_CHECKING: - from functools import cached_property - # The relative imports below are guarded by TYPE_CHECKING # because they would cause a circular import otherwise. from .config_entries import ConfigEntry from .helpers import device_registry as dr from .helpers.typing import ConfigType -else: - from .backports.functools import cached_property _CallableT = TypeVar("_CallableT", bound=Callable[..., Any]) diff --git a/homeassistant/util/yaml/loader.py b/homeassistant/util/yaml/loader.py index 28027c97211..d07b578628c 100644 --- a/homeassistant/util/yaml/loader.py +++ b/homeassistant/util/yaml/loader.py @@ -8,7 +8,7 @@ from io import StringIO, TextIOWrapper import logging import os from pathlib import Path -from typing import TYPE_CHECKING, Any, TextIO, TypeVar, overload +from typing import Any, TextIO, TypeVar, overload import yaml @@ -22,18 +22,14 @@ except ImportError: SafeLoader as FastestAvailableSafeLoader, ) +from functools import cached_property + from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.frame import report from .const import SECRET_YAML from .objects import Input, NodeDictClass, NodeListClass, NodeStrClass -if TYPE_CHECKING: - from functools import cached_property -else: - from homeassistant.backports.functools import cached_property - - # mypy: allow-untyped-calls, no-warn-return-any JSON_TYPE = list | dict | str diff --git a/pylint/plugins/hass_imports.py b/pylint/plugins/hass_imports.py index b8ec65e4460..d8f85df011f 100644 --- a/pylint/plugins/hass_imports.py +++ b/pylint/plugins/hass_imports.py @@ -25,6 +25,15 @@ _OBSOLETE_IMPORT: dict[str, list[ObsoleteImportMatch]] = { constant=re.compile(r"^StrEnum$"), ), ], + "homeassistant.backports.functools": [ + ObsoleteImportMatch( + reason=( + "We can now use the Python 3.12 provided " + "functools.cached_property instead" + ), + constant=re.compile(r"^cached_property$"), + ), + ], "homeassistant.components.alarm_control_panel": [ ObsoleteImportMatch( reason="replaced by AlarmControlPanelEntityFeature enum", diff --git a/tests/helpers/test_entity.py b/tests/helpers/test_entity.py index dac03f0be67..70d917dbc7b 100644 --- a/tests/helpers/test_entity.py +++ b/tests/helpers/test_entity.py @@ -5,6 +5,7 @@ from collections.abc import Iterable import dataclasses from datetime import timedelta from enum import IntFlag +from functools import cached_property import logging import threading from typing import Any @@ -15,7 +16,6 @@ import pytest from syrupy.assertion import SnapshotAssertion import voluptuous as vol -from homeassistant.backports.functools import cached_property from homeassistant.const import ( ATTR_ATTRIBUTION, ATTR_DEVICE_CLASS, diff --git a/tests/test_config_entries.py b/tests/test_config_entries.py index 6af5f2cde3f..b817aaddf5d 100644 --- a/tests/test_config_entries.py +++ b/tests/test_config_entries.py @@ -5,6 +5,7 @@ from __future__ import annotations import asyncio from collections.abc import Generator from datetime import timedelta +from functools import cached_property import logging from typing import Any from unittest.mock import ANY, AsyncMock, Mock, patch @@ -14,7 +15,6 @@ import pytest from syrupy.assertion import SnapshotAssertion from homeassistant import config_entries, data_entry_flow, loader -from homeassistant.backports.functools import cached_property from homeassistant.components import dhcp from homeassistant.components.hassio import HassioServiceInfo from homeassistant.const import (