Brad Bishop | 1a4b7ee | 2018-12-16 17:11:34 -0800 | [diff] [blame] | 1 | From 39a7d79ee6c548902fbac8b95c934af7e4c69260 Mon Sep 17 00:00:00 2001 |
| 2 | From: Vendula Poncova <vponcova@redhat.com> |
| 3 | Date: Thu, 2 Aug 2018 15:30:45 +0800 |
| 4 | Subject: [PATCH 1/2] Support asynchronous calls (#58) |
| 5 | |
| 6 | Added support for asynchronous calls of methods. A method is called |
| 7 | synchronously unless its callback parameter is specified. A callback |
| 8 | is a function f(*args, returned=None, error=None), where args is |
| 9 | callback_args specified in the method call, returned is a return |
| 10 | value of the method and error is an exception raised by the method. |
| 11 | |
| 12 | Example of an asynchronous call: |
| 13 | |
| 14 | def func(x, y, returned=None, error=None): |
| 15 | pass |
| 16 | |
| 17 | proxy.Method(a, b, callback=func, callback_args=(x, y)) |
| 18 | |
| 19 | Upstream-Status: Cherry-pick [https://src.fedoraproject.org/cgit/rpms/python-pydbus.git/] |
| 20 | |
| 21 | Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com> |
| 22 | --- |
| 23 | pydbus/proxy_method.py | 44 ++++++++++++++++++++++++++++++++++++++------ |
| 24 | 1 file changed, 38 insertions(+), 6 deletions(-) |
| 25 | |
| 26 | diff --git a/pydbus/proxy_method.py b/pydbus/proxy_method.py |
| 27 | index 8798edd..4ea4304 100644 |
| 28 | --- a/pydbus/proxy_method.py |
| 29 | +++ b/pydbus/proxy_method.py |
| 30 | @@ -65,15 +65,34 @@ class ProxyMethod(object): |
| 31 | |
| 32 | # Python 2 sux |
| 33 | for kwarg in kwargs: |
| 34 | - if kwarg not in ("timeout",): |
| 35 | + if kwarg not in ("timeout", "callback", "callback_args"): |
| 36 | raise TypeError(self.__qualname__ + " got an unexpected keyword argument '{}'".format(kwarg)) |
| 37 | timeout = kwargs.get("timeout", None) |
| 38 | + callback = kwargs.get("callback", None) |
| 39 | + callback_args = kwargs.get("callback_args", tuple()) |
| 40 | + |
| 41 | + call_args = ( |
| 42 | + instance._bus_name, |
| 43 | + instance._path, |
| 44 | + self._iface_name, |
| 45 | + self.__name__, |
| 46 | + GLib.Variant(self._sinargs, args), |
| 47 | + GLib.VariantType.new(self._soutargs), |
| 48 | + 0, |
| 49 | + timeout_to_glib(timeout), |
| 50 | + None |
| 51 | + ) |
| 52 | + |
| 53 | + if callback: |
| 54 | + call_args += (self._finish_async_call, (callback, callback_args)) |
| 55 | + instance._bus.con.call(*call_args) |
| 56 | + return None |
| 57 | + else: |
| 58 | + ret = instance._bus.con.call_sync(*call_args) |
| 59 | + return self._unpack_return(ret) |
| 60 | |
| 61 | - ret = instance._bus.con.call_sync( |
| 62 | - instance._bus_name, instance._path, |
| 63 | - self._iface_name, self.__name__, GLib.Variant(self._sinargs, args), GLib.VariantType.new(self._soutargs), |
| 64 | - 0, timeout_to_glib(timeout), None).unpack() |
| 65 | - |
| 66 | + def _unpack_return(self, values): |
| 67 | + ret = values.unpack() |
| 68 | if len(self._outargs) == 0: |
| 69 | return None |
| 70 | elif len(self._outargs) == 1: |
| 71 | @@ -81,6 +100,19 @@ class ProxyMethod(object): |
| 72 | else: |
| 73 | return ret |
| 74 | |
| 75 | + def _finish_async_call(self, source, result, user_data): |
| 76 | + error = None |
| 77 | + return_args = None |
| 78 | + |
| 79 | + try: |
| 80 | + ret = source.call_finish(result) |
| 81 | + return_args = self._unpack_return(ret) |
| 82 | + except Exception as err: |
| 83 | + error = err |
| 84 | + |
| 85 | + callback, callback_args = user_data |
| 86 | + callback(*callback_args, returned=return_args, error=error) |
| 87 | + |
| 88 | def __get__(self, instance, owner): |
| 89 | if instance is None: |
| 90 | return self |
| 91 | -- |
| 92 | 2.7.4 |
| 93 | |