Improve performance of abort_entries_match (#98932)

* Improve performance of abort_entries_match

In #90406 a ChainMap was added which called __iter__
and __contains__ which ends up creating temp dicts
for matching

174e9da083/Lib/collections/__init__.py (L1022)

We can avoid this by removing the ChainMap since there
are only two mappings to match on.

This also means options no longer obscures data

* adjust comment
This commit is contained in:
J. Nick Koston 2023-08-24 08:34:45 -05:00 committed by GitHub
parent b145352bbb
commit 99e97782b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 14 additions and 13 deletions

View File

@ -2,7 +2,6 @@
from __future__ import annotations from __future__ import annotations
import asyncio import asyncio
from collections import ChainMap
from collections.abc import Callable, Coroutine, Generator, Iterable, Mapping from collections.abc import Callable, Coroutine, Generator, Iterable, Mapping
from contextvars import ContextVar from contextvars import ContextVar
from copy import deepcopy from copy import deepcopy
@ -1465,14 +1464,12 @@ def _async_abort_entries_match(
if match_dict is None: if match_dict is None:
match_dict = {} # Match any entry match_dict = {} # Match any entry
for entry in other_entries: for entry in other_entries:
if all( options_items = entry.options.items()
item data_items = entry.data.items()
in ChainMap( for kv in match_dict.items():
entry.options, # type: ignore[arg-type] if kv not in options_items and kv not in data_items:
entry.data, # type: ignore[arg-type] break
).items() else:
for item in match_dict.items()
):
raise data_entry_flow.AbortFlow("already_configured") raise data_entry_flow.AbortFlow("already_configured")

View File

@ -3379,11 +3379,13 @@ async def test_setup_retrying_during_shutdown(hass: HomeAssistant) -> None:
({"vendor": "zoo"}, "already_configured"), ({"vendor": "zoo"}, "already_configured"),
({"ip": "9.9.9.9"}, "already_configured"), ({"ip": "9.9.9.9"}, "already_configured"),
({"ip": "7.7.7.7"}, "no_match"), # ignored ({"ip": "7.7.7.7"}, "no_match"), # ignored
({"vendor": "data"}, "no_match"), # The next two data sets ensure options or data match
# as options previously shadowed data when matching.
({"vendor": "data"}, "already_configured"),
( (
{"vendor": "options"}, {"vendor": "options"},
"already_configured", "already_configured",
), # ensure options takes precedence over data ),
], ],
) )
async def test__async_abort_entries_match( async def test__async_abort_entries_match(
@ -3460,11 +3462,13 @@ async def test__async_abort_entries_match(
({"vendor": "zoo"}, "already_configured"), ({"vendor": "zoo"}, "already_configured"),
({"ip": "9.9.9.9"}, "already_configured"), ({"ip": "9.9.9.9"}, "already_configured"),
({"ip": "7.7.7.7"}, "no_match"), # ignored ({"ip": "7.7.7.7"}, "no_match"), # ignored
({"vendor": "data"}, "no_match"), # The next two data sets ensure options or data match
# as options previously shadowed data when matching.
({"vendor": "data"}, "already_configured"),
( (
{"vendor": "options"}, {"vendor": "options"},
"already_configured", "already_configured",
), # ensure options takes precedence over data ),
], ],
) )
async def test__async_abort_entries_match_options_flow( async def test__async_abort_entries_match_options_flow(