Add backport of cached_property from CPython 3.12 (#95292)
This commit is contained in:
parent
b02cb56988
commit
a568885ad2
7 changed files with 70 additions and 7 deletions
62
homeassistant/backports/functools.py
Normal file
62
homeassistant/backports/functools.py
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
"""Functools backports from standard lib."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Callable
|
||||||
|
from types import GenericAlias
|
||||||
|
from typing import Any, Generic, TypeVar, cast
|
||||||
|
|
||||||
|
_T = TypeVar("_T")
|
||||||
|
_R = TypeVar("_R")
|
||||||
|
|
||||||
|
|
||||||
|
class cached_property(Generic[_T, _R]): # pylint: disable=invalid-name
|
||||||
|
"""Backport of Python 3.12's cached_property.
|
||||||
|
|
||||||
|
Includes https://github.com/python/cpython/pull/101890/files
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, func: Callable[[_T], _R]) -> None:
|
||||||
|
"""Initialize."""
|
||||||
|
self.func = func
|
||||||
|
self.attrname: Any = None
|
||||||
|
self.__doc__ = func.__doc__
|
||||||
|
|
||||||
|
def __set_name__(self, owner: type[_T], 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})."
|
||||||
|
)
|
||||||
|
|
||||||
|
def __get__(self, instance: _T | None, owner: type[_T] | None = None) -> _R:
|
||||||
|
"""Get."""
|
||||||
|
if instance is None:
|
||||||
|
return cast(_R, 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)
|
|
@ -16,6 +16,7 @@ from async_upnp_client.profiles.dlna import ContentDirectoryErrorCode, DmsDevice
|
||||||
from didl_lite import didl_lite
|
from didl_lite import didl_lite
|
||||||
|
|
||||||
from homeassistant.backports.enum import StrEnum
|
from homeassistant.backports.enum import StrEnum
|
||||||
|
from homeassistant.backports.functools import cached_property
|
||||||
from homeassistant.components import ssdp
|
from homeassistant.components import ssdp
|
||||||
from homeassistant.components.media_player import BrowseError, MediaClass
|
from homeassistant.components.media_player import BrowseError, MediaClass
|
||||||
from homeassistant.components.media_source.error import Unresolvable
|
from homeassistant.components.media_source.error import Unresolvable
|
||||||
|
@ -619,7 +620,7 @@ class DmsDeviceSource:
|
||||||
"""Make an identifier for BrowseMediaSource."""
|
"""Make an identifier for BrowseMediaSource."""
|
||||||
return f"{self.source_id}/{action}{object_id}"
|
return f"{self.source_id}/{action}{object_id}"
|
||||||
|
|
||||||
@functools.cached_property
|
@cached_property
|
||||||
def _sort_criteria(self) -> list[str]:
|
def _sort_criteria(self) -> list[str]:
|
||||||
"""Return criteria to be used for sorting results.
|
"""Return criteria to be used for sorting results.
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from functools import cached_property
|
|
||||||
import logging
|
import logging
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
@ -11,6 +10,7 @@ from fints.client import FinTS3PinTanClient
|
||||||
from fints.models import SEPAAccount
|
from fints.models import SEPAAccount
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant.backports.functools import cached_property
|
||||||
from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity
|
from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity
|
||||||
from homeassistant.const import CONF_NAME, CONF_PIN, CONF_URL, CONF_USERNAME
|
from homeassistant.const import CONF_NAME, CONF_PIN, CONF_URL, CONF_USERNAME
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
|
@ -5,7 +5,6 @@ import asyncio
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from collections.abc import Callable, Iterable
|
from collections.abc import Callable, Iterable
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from functools import cached_property
|
|
||||||
from typing import Any, Generic, TypeVar
|
from typing import Any, Generic, TypeVar
|
||||||
|
|
||||||
from nibe.coil import Coil, CoilData
|
from nibe.coil import Coil, CoilData
|
||||||
|
@ -15,6 +14,7 @@ from nibe.connection.nibegw import NibeGW, ProductInfo
|
||||||
from nibe.exceptions import CoilNotFoundException, ReadException
|
from nibe.exceptions import CoilNotFoundException, ReadException
|
||||||
from nibe.heatpump import HeatPump, Model, Series
|
from nibe.heatpump import HeatPump, Model, Series
|
||||||
|
|
||||||
|
from homeassistant.backports.functools import cached_property
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONF_IP_ADDRESS,
|
CONF_IP_ADDRESS,
|
||||||
|
|
|
@ -3,13 +3,13 @@ from __future__ import annotations
|
||||||
|
|
||||||
import dataclasses
|
import dataclasses
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from functools import cached_property
|
|
||||||
import logging
|
import logging
|
||||||
from typing import Any, cast
|
from typing import Any, cast
|
||||||
|
|
||||||
from python_otbr_api import tlv_parser
|
from python_otbr_api import tlv_parser
|
||||||
from python_otbr_api.tlv_parser import MeshcopTLVType
|
from python_otbr_api.tlv_parser import MeshcopTLVType
|
||||||
|
|
||||||
|
from homeassistant.backports.functools import cached_property
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.helpers.singleton import singleton
|
from homeassistant.helpers.singleton import singleton
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
"""Lighting cluster handlers module for Zigbee Home Automation."""
|
"""Lighting cluster handlers module for Zigbee Home Automation."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from functools import cached_property
|
|
||||||
|
|
||||||
from zigpy.zcl.clusters import lighting
|
from zigpy.zcl.clusters import lighting
|
||||||
|
|
||||||
|
from homeassistant.backports.functools import cached_property
|
||||||
|
|
||||||
from .. import registries
|
from .. import registries
|
||||||
from ..const import REPORT_CONFIG_DEFAULT
|
from ..const import REPORT_CONFIG_DEFAULT
|
||||||
from . import AttrReportConfig, ClientClusterHandler, ClusterHandler
|
from . import AttrReportConfig, ClientClusterHandler, ClusterHandler
|
||||||
|
|
|
@ -5,7 +5,6 @@ import asyncio
|
||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from functools import cached_property
|
|
||||||
import logging
|
import logging
|
||||||
import random
|
import random
|
||||||
import time
|
import time
|
||||||
|
@ -23,6 +22,7 @@ from zigpy.zcl.clusters.general import Groups, Identify
|
||||||
from zigpy.zcl.foundation import Status as ZclStatus, ZCLCommandDef
|
from zigpy.zcl.foundation import Status as ZclStatus, ZCLCommandDef
|
||||||
import zigpy.zdo.types as zdo_types
|
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.const import ATTR_COMMAND, ATTR_DEVICE_ID, ATTR_NAME
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue