Skip to content

Commit 86878a7

Browse files
authored
feat: remove dacite (#227)
1 parent 2731bce commit 86878a7

File tree

2 files changed

+64
-9
lines changed

2 files changed

+64
-9
lines changed

roborock/containers.py

Lines changed: 63 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@
77
from dataclasses import asdict, dataclass, field
88
from datetime import timezone
99
from enum import Enum
10-
from typing import Any, NamedTuple
11-
12-
from dacite import Config, from_dict
10+
from typing import Any, NamedTuple, get_args, get_origin
1311

1412
from .code_mappings import (
1513
RoborockCategory,
@@ -102,14 +100,70 @@ class RoborockBase:
102100
_ignore_keys = [] # type: ignore
103101
is_cached = False
104102

103+
@staticmethod
104+
def convert_to_class_obj(type, value):
105+
try:
106+
class_type = eval(type)
107+
if get_origin(class_type) is list:
108+
return_list = []
109+
cls_type = get_args(class_type)[0]
110+
for obj in value:
111+
if issubclass(cls_type, RoborockBase):
112+
return_list.append(cls_type.from_dict(obj))
113+
elif cls_type in {str, int, float}:
114+
return_list.append(cls_type(obj))
115+
else:
116+
return_list.append(cls_type(**obj))
117+
return return_list
118+
if issubclass(class_type, RoborockBase):
119+
converted_value = class_type.from_dict(value)
120+
else:
121+
converted_value = class_type(value)
122+
return converted_value
123+
except NameError as err:
124+
_LOGGER.exception(err)
125+
except ValueError as err:
126+
_LOGGER.exception(err)
127+
except Exception as err:
128+
_LOGGER.exception(err)
129+
raise Exception("Fail")
130+
105131
@classmethod
106132
def from_dict(cls, data: dict[str, Any]):
107133
if isinstance(data, dict):
108134
ignore_keys = cls._ignore_keys
109-
try:
110-
return from_dict(cls, decamelize_obj(data, ignore_keys), config=Config(cast=[Enum]))
111-
except AttributeError as err:
112-
raise RoborockException("It seems like you have an outdated version of dacite.") from err
135+
data = decamelize_obj(data, ignore_keys)
136+
cls_annotations: dict[str, str] = {}
137+
for base in reversed(cls.__mro__):
138+
cls_annotations.update(getattr(base, "__annotations__", {}))
139+
remove_keys = []
140+
for key, value in data.items():
141+
if value == "None" or value is None:
142+
data[key] = None
143+
continue
144+
if key not in cls_annotations:
145+
remove_keys.append(key)
146+
continue
147+
field_type: str = cls_annotations[key]
148+
if "|" in field_type:
149+
# It's a union
150+
types = field_type.split("|")
151+
for type in types:
152+
if "None" in type or "Any" in type:
153+
continue
154+
try:
155+
data[key] = RoborockBase.convert_to_class_obj(type, value)
156+
break
157+
except Exception:
158+
...
159+
else:
160+
try:
161+
data[key] = RoborockBase.convert_to_class_obj(field_type, value)
162+
except Exception:
163+
...
164+
for key in remove_keys:
165+
del data[key]
166+
return cls(**data)
113167

114168
def as_dict(self) -> dict:
115169
return asdict(
@@ -185,6 +239,7 @@ class HomeDataProductSchema(RoborockBase):
185239
mode: Any | None = None
186240
type: Any | None = None
187241
product_property: Any | None = None
242+
property: Any | None = None
188243
desc: Any | None = None
189244

190245

@@ -195,7 +250,7 @@ class HomeDataProduct(RoborockBase):
195250
model: str
196251
category: RoborockCategory
197252
code: str | None = None
198-
iconurl: str | None = None
253+
icon_url: str | None = None
199254
attribute: Any | None = None
200255
capability: int | None = None
201256
schema: list[HomeDataProductSchema] | None = None

tests/test_containers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def test_home_data():
4747
assert product.name == "Roborock S7 MaxV"
4848
assert product.code == "a27"
4949
assert product.model == "roborock.vacuum.a27"
50-
assert product.iconurl is None
50+
assert product.icon_url is None
5151
assert product.attribute is None
5252
assert product.capability == 0
5353
assert product.category == RoborockCategory.VACUUM

0 commit comments

Comments
 (0)