custom-components / pyscript

Pyscript adds rich Python scripting to HASS
Apache License 2.0
874 stars 46 forks source link

Dataclasses are not working in scripts #537

Closed binaryaaron closed 11 months ago

binaryaaron commented 11 months ago

Hi! First off, it's am amazing framework and I love using it instead of a billion yaml files to run my house. Thanks for your efforts.

I just noticed that a simple dataclass doesn't work, likely due to lack of an async def ast_annassign(...) function in eval.py.

e.g., i've had an existing script that broke after upgrading to 1.5 + HASS 2023.10.0

from dataclasses import dataclass

...

@dataclass
class HVACSettings:
    mode: str
    temp: int
    fan_speed: str
    time_trigger: str

and in my logs:

2023-10-18 14:47:57.010 ERROR (MainThread) [custom_components.pyscript.file.hvac] Exception in </config/pyscript/hvac.py> line 53:
        mode: str
        ^
NotImplementedError: file.hvac: not implemented ast ast_annassign

Curious if this was ever supposed to work or something else has changed. Could probably make a PR here to fix if you think adding the ast_anassign method is "right".

craigbarratt commented 11 months ago

It would be great if you could submit a PR with support for ast_annassign.

craigbarratt commented 11 months ago

I went ahead and added ast_annassign.

binaryaaron commented 11 months ago

Thanks!

phyrwork commented 8 months ago

Is there a release scheduled? I have this problem and would appreciate this fix.

contagon commented 4 months ago

I'm also unsure if this is actually working. Running off the master branch allows it to load with error, but when running it appears the attributes are never set.

from dataclasses import dataclass

@dataclass
class MyClass:
    name: str

c = MyClass("Foo")
log.warning(c.name)

Results in

Exception in </config/pyscript/myfile.py> line 11:
    log.warning(c.name)
                ^
AttributeError: 'MyClass' object has no attribute 'name'

If anyone knows a workaround, I'm all ears!

EDIT: Figured out my own problem, similar solution to using enums,

from dataclasses import make_dataclass

MyClass = make_dataclass("MyClass", [("name", int)])