Open jonasBoss opened 2 years ago
This is a fantastic improvement.
My use case that requires it is pytest. I have a class that has been exposed as a ServiceInterface, but I still want to be able to use pytest to directly create it and call methods on it without going through dbus. Without this added 'return', the called methods always just return None.
Now I can easily have some pytests use dbus and others use the class directly and it all still works.
since there is no movement on this PR: #123 Here is a fix which can be deployed without touching the dbus-next library
def fix_non_returning_decorator(decorator):
def fixed_decorator(fn):
retval = None
@decorator
@functools.wraps(fn)
def non_returning_fn(*args, **kwargs):
nonlocal retval
retval = fn(*args, **kwargs)
return retval # this return gets eaten by the decorator
@functools.wraps(non_returning_fn)
def returning_fn(*args, **kwargs):
non_returning_fn(*args, **kwargs)
return retval
return returning_fn
return fixed_decorator
class MyAwesomeInterface(service.ServiceInterface):
@fix_non_returning_decorator(service.method())
def cool_method() -> 's':
return "Hi there!"
Unfortunately this breaks async functions.
Better workaround, which does not break async functions:
This does rely a bit on dbus-next internals.
from dbus_next import service
def method(name: str = None, disabled: bool = False):
# this is a workaround for https://github.com/altdesktop/python-dbus-next/issues/119
@typing.no_type_check_decorator
def fixed_decorator(fn):
# we don't actually decorate the function
# dbus-next only cares about the __dict__
fn.__dict__ = service.method(name, disabled)(fn).__dict__
return fn
return fixed_decorator
The wrapped method in
service.method()
(service.py line 91) does not return the value from the original method. This is confusing and limits the utility of the interface.conciser the following:
calling
do_more_things
will raise a error:adding a return statement seems to fix this issue: