Skip to content

Commit b33b258

Browse files
committed
assignment of StateVar to a state variable assigns value and attrs
1 parent 4bee085 commit b33b258

File tree

2 files changed

+31
-4
lines changed

2 files changed

+31
-4
lines changed

custom_components/pyscript/state.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
_LOGGER = logging.getLogger(LOGGER_PATH + ".state")
1414

15+
STATE_VIRTUAL_ATTRS = {"last_changed", "last_updated"}
16+
1517

1618
class StateVar(str):
1719
"""Class for representing the value and attributes of a state variable."""
@@ -143,6 +145,15 @@ async def set(cls, var_name, value=None, new_attributes=None, **kwargs):
143145
if var_name.count(".") != 1:
144146
raise NameError(f"invalid name {var_name} (should be 'domain.entity')")
145147

148+
if isinstance(value, StateVar) and new_attributes is None:
149+
#
150+
# value is a StateVar, so extract the attributes and value
151+
#
152+
new_attributes = value.__dict__.copy()
153+
for discard in STATE_VIRTUAL_ATTRS:
154+
new_attributes.pop(discard, None)
155+
value = str(value)
156+
146157
state_value = None
147158
if value is None or new_attributes is None:
148159
state_value = cls.hass.states.get(var_name)
@@ -218,7 +229,7 @@ def exist(cls, var_name):
218229
len(parts) == 2
219230
or (parts[0] in cls.service2args and parts[2] in cls.service2args[parts[0]])
220231
or parts[2] in value.attributes
221-
or parts[2] in {"last_changed", "last_updated"}
232+
or parts[2] in STATE_VIRTUAL_ATTRS
222233
):
223234
return True
224235
return False
@@ -302,7 +313,7 @@ def completions(cls, root):
302313
value = cls.hass.states.get(name)
303314
if value:
304315
attr_root = root[last_period + 1 :]
305-
attrs = set(value.attributes.keys()).union({"last_changed", "last_updated"})
316+
attrs = set(value.attributes.keys()).union(STATE_VIRTUAL_ATTRS)
306317
if parts[0] in cls.service2args:
307318
attrs.update(set(cls.service2args[parts[0]].keys()))
308319
for attr_name in attrs:

tests/test_unit_eval.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@
141141
state.set("pyscript.var1", 100, attr1=1, attr2=3.5)
142142
chk = [[pyscript.var1.attr1, pyscript.var1.attr2]]
143143
pyscript.var1 += "xyz"
144-
chk.append([pyscript.var1.attr1, pyscript.var1.attr2])
144+
chk.append([pyscript.var1, pyscript.var1.attr1, pyscript.var1.attr2])
145145
state.set("pyscript.var1", 200, attr3 = 'abc')
146146
chk.append([pyscript.var1.attr1, pyscript.var1.attr2, pyscript.var1.attr3])
147147
chk.append(state.getattr("pyscript.var1"))
@@ -163,7 +163,7 @@
163163
""",
164164
[
165165
[1, 3.5],
166-
[1, 3.5],
166+
["100xyz", 1, 3.5],
167167
[1, 3.5, "abc"],
168168
{"attr1": 1, "attr2": 3.5, "attr3": "abc"},
169169
{},
@@ -175,6 +175,22 @@
175175
"200",
176176
],
177177
],
178+
[
179+
"""
180+
state.set("pyscript.var1", 100, attr1=1, attr2=3.5)
181+
s = pyscript.var1
182+
chk = [[s, s.attr1, s.attr2]]
183+
s.attr2 += 6.5
184+
chk.append([s, s.attr1, s.attr2])
185+
s.attr3 = 100
186+
chk.append([s, s.attr1, s.attr2, s.attr3])
187+
pyscript.var1 = 0
188+
pyscript.var1 = s
189+
chk.append([pyscript.var1, pyscript.var1.attr1, pyscript.var1.attr2, pyscript.var1.attr3])
190+
chk
191+
""",
192+
[["100", 1, 3.5], ["100", 1, 10], ["100", 1, 10, 100], ["100", 1, 10, 100]],
193+
],
178194
["eval('1+2')", 3],
179195
["x = 5; eval('2 * x')", 10],
180196
["x = 5; exec('x = 2 * x'); x", 10],

0 commit comments

Comments
 (0)