appdaemon icon indicating copy to clipboard operation
appdaemon copied to clipboard

listen_xxx functions dont allow objetcs as custom kwargs

Open mmattel opened this issue 1 year ago • 4 comments

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):

mmattel avatar Sep 25 '24 09:09 mmattel

@jsl12 @acockburn Q: is this addressed in 4.5.x ?

mmattel avatar May 28 '25 08:05 mmattel

No it isn't, but we still have it on the radar.

acockburn avatar May 28 '25 11:05 acockburn

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

jsl12 avatar May 29 '25 20:05 jsl12

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.

github-actions[bot] avatar Nov 30 '25 02:11 github-actions[bot]