listen_xxx functions dont allow objetcs as custom kwargs
What happened?
I have a setup where an app includes another module. To make the app slim, all major functions are located in that included module. Therefore I handover self as function call parameter and is used as iself in the modules code. This works flawless like for logging. But it breaks when using listeners with custom arguments (kwargs) at the end, see the examples:
Docs does not state any limitations with respect to the type of the value of the named argument, therefore this is either a bug or the docs need to be more precise about the value types allowed.
Version
4.4.2
Installation type
Docker container
Relevant log output
When using an object as kwarg value, this error raises:
Traceback (most recent call last): File "/usr/local/lib/python3.10/site-packages/appdaemon/events.py", line 249, in process_event mydata = deepcopy(data) File "/usr/local/lib/python3.10/copy.py", line 146, in deepcopy y = copier(x, memo) File "/usr/local/lib/python3.10/copy.py", line 231, in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) File "/usr/local/lib/python3.10/copy.py", line 146, in deepcopy y = copier(x, memo) File "/usr/local/lib/python3.10/copy.py", line 231, in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) File "/usr/local/lib/python3.10/copy.py", line 146, in deepcopy y = copier(x, memo) File "/usr/local/lib/python3.10/copy.py", line 231, in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) File "/usr/local/lib/python3.10/copy.py", line 146, in deepcopy y = copier(x, memo) File "/usr/local/lib/python3.10/copy.py", line 231, in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) File "/usr/local/lib/python3.10/copy.py", line 146, in deepcopy y = copier(x, memo) File "/usr/local/lib/python3.10/copy.py", line 231, in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) File "/usr/local/lib/python3.10/copy.py", line 172, in deepcopy y = _reconstruct(x, memo, *rv) File "/usr/local/lib/python3.10/copy.py", line 271, in _reconstruct state = deepcopy(state, memo) File "/usr/local/lib/python3.10/copy.py", line 146, in deepcopy y = copier(x, memo) File "/usr/local/lib/python3.10/copy.py", line 231, in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) File "/usr/local/lib/python3.10/copy.py", line 172, in deepcopy y = _reconstruct(x, memo, *rv) File "/usr/local/lib/python3.10/copy.py", line 271, in _reconstruct state = deepcopy(state, memo) File "/usr/local/lib/python3.10/copy.py", line 146, in deepcopy y = copier(x, memo) File "/usr/local/lib/python3.10/copy.py", line 231, in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) File "/usr/local/lib/python3.10/copy.py", line 172, in deepcopy y = _reconstruct(x, memo, *rv) File "/usr/local/lib/python3.10/copy.py", line 271, in _reconstruct state = deepcopy(state, memo) File "/usr/local/lib/python3.10/copy.py", line 146, in deepcopy y = copier(x, memo) File "/usr/local/lib/python3.10/copy.py", line 231, in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) File "/usr/local/lib/python3.10/copy.py", line 146, in deepcopy y = copier(x, memo) File "/usr/local/lib/python3.10/copy.py", line 231, in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) File "/usr/local/lib/python3.10/copy.py", line 146, in deepcopy y = copier(x, memo) File "/usr/local/lib/python3.10/copy.py", line 231, in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) File "/usr/local/lib/python3.10/copy.py", line 172, in deepcopy y = _reconstruct(x, memo, *rv) File "/usr/local/lib/python3.10/copy.py", line 271, in _reconstruct state = deepcopy(state, memo) File "/usr/local/lib/python3.10/copy.py", line 146, in deepcopy y = copier(x, memo) File "/usr/local/lib/python3.10/copy.py", line 231, in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) File "/usr/local/lib/python3.10/copy.py", line 161, in deepcopy rv = reductor(4) TypeError: cannot pickle '_thread.RLock' object
Relevant code in the app or config file that caused the issue
Works
...
iself.listen_state(entity_cb, entityID)
def entity_cb(entity, attribute, old, new, kwargs):
Works
...
iself.listen_state(entity_cb, entityID, arg1="custom")
def entity_cb(entity, attribute, old, new, kwargs):
Fails
...
iself.listen_state(entity_cb, entityID, arg1=iself)
def entity_cb(entity, attribute, old, new, kwargs):
@jsl12 @acockburn Q: is this addressed in 4.5.x ?
No it isn't, but we still have it on the radar.
I've got an idea for how to fix this, but if it doesn't work, you might be out of luck with this specific implementation. There are other ways to break up your app into multiple, smaller files, and regardless of how you do it, anything you import should get automatically detected as a dependency by the new AppManagement system, so the hot reloading will work
This issue is stale because it has been open for 6 months with no activity. Remove stale label or comment or this will be closed in 15 days.