8000 Improve performance of dict merge code (#1097) · python-kasa/python-kasa@4669e08 · GitHub
[go: up one dir, main page]

Skip to content

Commit 4669e08

Browse files
bdracorytilahti
andauthored
Improve performance of dict merge code (#1097)
Co-authored-by: Teemu R. <tpr@iki.fi>
1 parent 633f57d commit 4669e08

File tree

3 files changed

+29
-20
lines changed

3 files changed

+29
-20
lines changed

kasa/iot/iotdevice.py

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
from __future__ import annotations
1616

17-
import collections.abc
1817
import functools
1918
import inspect
2019
import logging
@@ -29,22 +28,12 @@
2928
from ..module import Module
3029
from ..modulemapping import ModuleMapping, ModuleName
3130
from ..protocol import BaseProtocol
32-
from .iotmodule import IotModule
31+
from .iotmodule import IotModule, merge
3332
from .modules import Emeter
3433

3534
_LOGGER = logging.getLogger(__name__)
3635

3736

38-
def merge(d, u):
39-
"""Update dict recursively."""
40-
for k, v in u.items():
41-
if isinstance(v, collections.abc.Mapping):
42-
d[k] = merge(d.get(k, {}), v)
43-
else:
44-
d[k] = v
45-
return d
46-
47-
4837
def requires_update(f):
4938
"""Indicate that `update` should be called before accessing this method.""" # noqa: D202
5039
if inspect.iscoroutinefunction(f):

kasa/iot/iotmodule.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
"""Base class for IOT module implementations."""
22

3-
import collections
43
import logging
54

65
from ..exceptions import KasaException
@@ -9,15 +8,17 @@
98
_LOGGER = logging.getLogger(__name__)
109

1110

12-
# TODO: This is used for query constructing, check for a better place
13-
def merge(d, u):
11+
def _merge_dict(dest: dict, source: dict) -> dict:
1412
"""Update dict recursively."""
15-
for k, v in u.items():
16-
if isinstance(v, collections.abc.Mapping):
17-
d[k] = merge(d.get(k, {}), v)
13+
for k, v in source.items():
14+
if k in dest and type(v) is dict: # noqa: E721 - only accepts `dict` type
15+
_merge_dict(dest[k], v)
1816
else:
19-
d[k] = v
20-
return d
17+
dest[k] = v
18+
return dest
19+
20+
21+
merge = _merge_dict
2122

2223

2324
class IotModule(Module):

kasa/tests/test_iotdevice.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
from kasa import KasaException, Module
2020
from kasa.iot import IotDevice
21+
from kasa.iot.iotmodule import _merge_dict
2122

2223
from .conftest import get_device_for_fixture_protocol, handle_turn_on, turn_on
2324
from .device_fixtures import device_iot, has_emeter_iot, no_emeter_iot
@@ -292,3 +293,21 @@ async def test_get_modules():
292293

293294
module = dummy_device.modules.get(Module.Cloud)
294295
assert module is None
296+
297+
298+
def test_merge_dict():
299+
"""Test the recursive dict merge."""
300+
dest = {"a": 1, "b": {"c": 2, "d": 3}}
301+
source = {"b": {"c": 4, "e": 5}}
302+
assert _merge_dict(dest, source) == {"a": 1, "b": {"c": 4, "d": 3, "e": 5}}
303+
304+
dest = {"smartlife.iot.common.emeter": {"get_realtime": None}}
305+
source = {
306+
"smartlife.iot.common.emeter": {"get_daystat": {"month": 8, "year": 2024}}
307+
}
308+
assert _merge_dict(dest, source) == {
309+
"smartlife.iot.common.emeter": {
310+
"get_realtime": None,
311+
"get_daystat": {"month": 8, "year": 2024},
312+
}
313+
}

0 commit comments

Comments
 (0)
0