Closed
Description
Hello,
I am trying to load and store a config from a yaml, and I want to have a custom class able to be dumped and loaded from yaml.
I have this working outside of HASS/PyScript, but it totally bites the dust in PyScript.
Versions
Home Assistant Core: 2023.8.4
Home Assistant OS: 10.5
PyScript version: 1.5.0
HASS PyYAML library: 6.0.1
Debian PyYAML library: 6.0.1, and also worked on 5.3.1
(venv) jacobc@webprime:~/python_venv$ pip list | grep -i yaml
PyYAML 6.0.1
jacobc@webprime:~/python_venv$ deactivate
jacobc@webprime:~/python_venv$ pip list | grep -i yaml
PyYAML 5.3.1
Here we go, the MVP:
import yaml
from enum import Enum, Flag, auto
Action = Flag('Action', ['Press', 'Hold', 'TerminateHold', 'Indeterminate', 'Up', 'Down', 'Left', 'Right', 'Center'])
def Action_representer(dumper, data: Action):
"""
Custom representer for an enum.Flag subclass 'Action' to enable customized YAML dumping.
The function works by:
converting the binary representation of the Action value into a set of power-of-two components,
joining their corresponding Action names with '|',
and then representing the result as a scalar in the YAML format.
For instance:
Action.Hold -> "!Action 'Hold'"
Action.Hold | Action.Center -> "!Action 'Hold|Center'"
Args:
dumper: YAML dumper instance.
data (Action): The Action object to be represented in the YAML format.
Returns:
Represents the Action object as a scalar in the custom YAML format.
"""
binary_str = bin(data.value)[2:][::-1]
binary_pieces = [2**(i+0) for i, bit in enumerate(binary_str) if bit == '1']
repr_str = '|'.join([Action(x).name for x in binary_pieces])
return dumper.represent_scalar(u'!Action', repr_str)
yaml.add_representer(Action, Action_representer)
print(yaml.dump(Action.Hold))
Debian Host:
This outputs as expected in an ipython shell,
In [4]: print(yaml.dump(Action.Hold))
!Action 'Hold'
Inside of PyScript:
Before running yaml.add_representer(Action, Action_representer)
log.info(yaml.dump({'hello': Action.Hold}))
->
2023-10-23 22:16:21.202 INFO (MainThread) [custom_components.pyscript.file.example.async_foo] hello: !!python/object/apply:builtins.getattr
- !!python/name:custom_components.pyscript.eval.Action ''
- Hold
After running yaml.add_representer(Action, Action_representer)
log.info(yaml.dump({'hello': Action.Hold}))
->
2023-10-23 22:16:41.349 ERROR (MainThread) [custom_components.pyscript.file.example.async_foo] Exception in <file.example.async_foo> line 196:
log.info(yaml.dump({'hello': Action.Hold}))
^
EmitterError: expected NodeEvent, but got MappingEndEvent()
No clue where to even start here, there isn't much on Google that is very helpful. Anyone have thoughts? Ideas?
All the best,
Jacob C.
Metadata
Metadata
Assignees
Labels
No labels