diff --git a/homeassistant/components/bluetooth/match.py b/homeassistant/components/bluetooth/match.py index 1315d0a834a0..827006fe19d2 100644 --- a/homeassistant/components/bluetooth/match.py +++ b/homeassistant/components/bluetooth/match.py @@ -7,7 +7,7 @@ from functools import lru_cache import re from typing import TYPE_CHECKING, Final, Generic, TypedDict, TypeVar -from lru import LRU # pylint: disable=no-name-in-module +from lru import LRU from homeassistant.core import callback from homeassistant.loader import BluetoothMatcher, BluetoothMatcherOptional @@ -15,8 +15,6 @@ from homeassistant.loader import BluetoothMatcher, BluetoothMatcherOptional from .models import BluetoothCallback, BluetoothServiceInfoBleak if TYPE_CHECKING: - from collections.abc import MutableMapping - from bleak.backends.scanner import AdvertisementData @@ -97,10 +95,8 @@ class IntegrationMatcher: self._integration_matchers = integration_matchers # Some devices use a random address so we need to use # an LRU to avoid memory issues. - self._matched: MutableMapping[str, IntegrationMatchHistory] = LRU( - MAX_REMEMBER_ADDRESSES - ) - self._matched_connectable: MutableMapping[str, IntegrationMatchHistory] = LRU( + self._matched: LRU[str, IntegrationMatchHistory] = LRU(MAX_REMEMBER_ADDRESSES) + self._matched_connectable: LRU[str, IntegrationMatchHistory] = LRU( MAX_REMEMBER_ADDRESSES ) self._index = BluetoothMatcherIndex() diff --git a/homeassistant/components/http/static.py b/homeassistant/components/http/static.py index 1ab4ef5bd6f6..7fe359d6486c 100644 --- a/homeassistant/components/http/static.py +++ b/homeassistant/components/http/static.py @@ -1,7 +1,7 @@ """Static file handling for HTTP component.""" from __future__ import annotations -from collections.abc import Mapping, MutableMapping +from collections.abc import Mapping import mimetypes from pathlib import Path from typing import Final @@ -10,7 +10,7 @@ from aiohttp import hdrs from aiohttp.web import FileResponse, Request, StreamResponse from aiohttp.web_exceptions import HTTPForbidden, HTTPNotFound from aiohttp.web_urldispatcher import StaticResource -from lru import LRU # pylint: disable=no-name-in-module +from lru import LRU from homeassistant.core import HomeAssistant @@ -19,9 +19,7 @@ from .const import KEY_HASS CACHE_TIME: Final = 31 * 86400 # = 1 month CACHE_HEADER = f"public, max-age={CACHE_TIME}" CACHE_HEADERS: Mapping[str, str] = {hdrs.CACHE_CONTROL: CACHE_HEADER} -PATH_CACHE: MutableMapping[ - tuple[str, Path, bool], tuple[Path | None, str | None] -] = LRU(512) +PATH_CACHE: LRU[tuple[str, Path, bool], tuple[Path | None, str | None]] = LRU(512) def _get_file_path(rel_url: str, directory: Path, follow_symlinks: bool) -> Path | None: diff --git a/homeassistant/components/profiler/__init__.py b/homeassistant/components/profiler/__init__.py index 8c5c206ae9ff..5e4408bba20b 100644 --- a/homeassistant/components/profiler/__init__.py +++ b/homeassistant/components/profiler/__init__.py @@ -11,7 +11,7 @@ import time import traceback from typing import Any, cast -from lru import LRU # pylint: disable=no-name-in-module +from lru import LRU import voluptuous as vol from homeassistant.components import persistent_notification diff --git a/homeassistant/components/recorder/table_managers/__init__.py b/homeassistant/components/recorder/table_managers/__init__.py index e56ee4f3415e..9a0945dc4d95 100644 --- a/homeassistant/components/recorder/table_managers/__init__.py +++ b/homeassistant/components/recorder/table_managers/__init__.py @@ -1,9 +1,8 @@ """Managers for each table.""" -from collections.abc import MutableMapping from typing import TYPE_CHECKING, Generic, TypeVar -from lru import LRU # pylint: disable=no-name-in-module +from lru import LRU if TYPE_CHECKING: from ..core import Recorder @@ -14,6 +13,8 @@ _DataT = TypeVar("_DataT") class BaseTableManager(Generic[_DataT]): """Base class for table managers.""" + _id_map: "LRU[str, int]" + def __init__(self, recorder: "Recorder") -> None: """Initialize the table manager. @@ -24,7 +25,6 @@ class BaseTableManager(Generic[_DataT]): self.active = False self.recorder = recorder self._pending: dict[str, _DataT] = {} - self._id_map: MutableMapping[str, int] = {} def get_from_cache(self, data: str) -> int | None: """Resolve data to the id without accessing the underlying database. @@ -62,7 +62,7 @@ class BaseLRUTableManager(BaseTableManager[_DataT]): and evict the least recently used items when the cache is full. """ super().__init__(recorder) - self._id_map: MutableMapping[str, int] = LRU(lru_size) + self._id_map = LRU(lru_size) def adjust_lru_size(self, new_size: int) -> None: """Adjust the LRU cache size. @@ -70,6 +70,6 @@ class BaseLRUTableManager(BaseTableManager[_DataT]): This call is not thread-safe and must be called from the recorder thread. """ - lru: LRU = self._id_map + lru = self._id_map if new_size > lru.get_size(): lru.set_size(new_size) diff --git a/homeassistant/components/recorder/table_managers/event_types.py b/homeassistant/components/recorder/table_managers/event_types.py index 45b3b96353c6..c74684a0f775 100644 --- a/homeassistant/components/recorder/table_managers/event_types.py +++ b/homeassistant/components/recorder/table_managers/event_types.py @@ -4,7 +4,7 @@ from __future__ import annotations from collections.abc import Iterable from typing import TYPE_CHECKING, cast -from lru import LRU # pylint: disable=no-name-in-module +from lru import LRU from sqlalchemy.orm.session import Session from homeassistant.core import Event @@ -28,7 +28,7 @@ class EventTypeManager(BaseLRUTableManager[EventTypes]): def __init__(self, recorder: Recorder) -> None: """Initialize the event type manager.""" super().__init__(recorder, CACHE_SIZE) - self._non_existent_event_types: LRU = LRU(CACHE_SIZE) + self._non_existent_event_types: LRU[str, None] = LRU(CACHE_SIZE) def load(self, events: list[Event], session: Session) -> None: """Load the event_type to event_type_ids mapping into memory. diff --git a/homeassistant/components/recorder/table_managers/statistics_meta.py b/homeassistant/components/recorder/table_managers/statistics_meta.py index a484bdf145e7..76def3a22fe5 100644 --- a/homeassistant/components/recorder/table_managers/statistics_meta.py +++ b/homeassistant/components/recorder/table_managers/statistics_meta.py @@ -5,7 +5,7 @@ import logging import threading from typing import TYPE_CHECKING, Literal, cast -from lru import LRU # pylint: disable=no-name-in-module +from lru import LRU from sqlalchemy import lambda_stmt, select from sqlalchemy.orm.session import Session from sqlalchemy.sql.expression import true @@ -74,7 +74,7 @@ class StatisticsMetaManager: def __init__(self, recorder: Recorder) -> None: """Initialize the statistics meta manager.""" self.recorder = recorder - self._stat_id_to_id_meta: dict[str, tuple[int, StatisticMetaData]] = LRU( + self._stat_id_to_id_meta: LRU[str, tuple[int, StatisticMetaData]] = LRU( CACHE_SIZE ) diff --git a/homeassistant/helpers/template.py b/homeassistant/helpers/template.py index df8b1c1e0197..9bb3759672fb 100644 --- a/homeassistant/helpers/template.py +++ b/homeassistant/helpers/template.py @@ -5,7 +5,7 @@ from ast import literal_eval import asyncio import base64 import collections.abc -from collections.abc import Callable, Collection, Generator, Iterable, MutableMapping +from collections.abc import Callable, Collection, Generator, Iterable from contextlib import AbstractContextManager, suppress from contextvars import ContextVar from datetime import datetime, timedelta @@ -40,7 +40,7 @@ from jinja2 import pass_context, pass_environment, pass_eval_context from jinja2.runtime import AsyncLoopContext, LoopContext from jinja2.sandbox import ImmutableSandboxedEnvironment from jinja2.utils import Namespace -from lru import LRU # pylint: disable=no-name-in-module +from lru import LRU import orjson import voluptuous as vol @@ -147,10 +147,8 @@ EVAL_CACHE_SIZE = 512 MAX_CUSTOM_TEMPLATE_SIZE = 5 * 1024 * 1024 -CACHED_TEMPLATE_LRU: MutableMapping[State, TemplateState] = LRU(CACHED_TEMPLATE_STATES) -CACHED_TEMPLATE_NO_COLLECT_LRU: MutableMapping[State, TemplateState] = LRU( - CACHED_TEMPLATE_STATES -) +CACHED_TEMPLATE_LRU: LRU[State, TemplateState] = LRU(CACHED_TEMPLATE_STATES) +CACHED_TEMPLATE_NO_COLLECT_LRU: LRU[State, TemplateState] = LRU(CACHED_TEMPLATE_STATES) ENTITY_COUNT_GROWTH_FACTOR = 1.2 ORJSON_PASSTHROUGH_OPTIONS = ( @@ -187,9 +185,9 @@ def async_setup(hass: HomeAssistant) -> bool: ) for lru in (CACHED_TEMPLATE_LRU, CACHED_TEMPLATE_NO_COLLECT_LRU): # There is no typing for LRU - current_size = lru.get_size() # type: ignore[attr-defined] + current_size = lru.get_size() if new_size > current_size: - lru.set_size(new_size) # type: ignore[attr-defined] + lru.set_size(new_size) from .event import ( # pylint: disable=import-outside-toplevel async_track_time_interval, diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index a4b218b59f2b..9a1af1fe9f54 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -33,7 +33,7 @@ httpx==0.25.0 ifaddr==0.2.0 janus==1.0.0 Jinja2==3.1.2 -lru-dict==1.2.0 +lru-dict==1.3.0 mutagen==1.47.0 orjson==3.9.9 packaging>=23.1 diff --git a/pyproject.toml b/pyproject.toml index 2e992da0ab3a..304d2844cad9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -40,7 +40,7 @@ dependencies = [ "home-assistant-bluetooth==1.11.0", "ifaddr==0.2.0", "Jinja2==3.1.2", - "lru-dict==1.2.0", + "lru-dict==1.3.0", "PyJWT==2.8.0", # PyJWT has loose dependency. We want the latest one. "cryptography==41.0.7", diff --git a/requirements.txt b/requirements.txt index 4faf7f8b2c22..b9430b1bc910 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,7 +18,7 @@ httpx==0.25.0 home-assistant-bluetooth==1.11.0 ifaddr==0.2.0 Jinja2==3.1.2 -lru-dict==1.2.0 +lru-dict==1.3.0 PyJWT==2.8.0 cryptography==41.0.7 pyOpenSSL==23.2.0 diff --git a/tests/components/profiler/test_init.py b/tests/components/profiler/test_init.py index 7c2aeb2a29ac..b8a81a40e37c 100644 --- a/tests/components/profiler/test_init.py +++ b/tests/components/profiler/test_init.py @@ -5,7 +5,7 @@ import os from pathlib import Path from unittest.mock import patch -from lru import LRU # pylint: disable=no-name-in-module +from lru import LRU import pytest from homeassistant.components.profiler import (