summaryrefslogtreecommitdiffstats
path: root/meta-python/recipes-devtools/python/python3-pydbus/0002-Support-asynchronous-calls-58.patch
diff options
context:
space:
mode:
authorDerek Straka <derek@asterius.io>2024-03-22 16:59:54 +0000
committerKhem Raj <raj.khem@gmail.com>2024-03-22 21:19:50 -0700
commit3c188f75eabf3cb2c976e69e4c18c401e20635dd (patch)
tree56d5082157836964843fa69dfd8d1b3b397e1bc1 /meta-python/recipes-devtools/python/python3-pydbus/0002-Support-asynchronous-calls-58.patch
parent1cb0dae6b8bddcef854aa30a61af8213b638a63a (diff)
downloadmeta-openembedded-3c188f75eabf3cb2c976e69e4c18c401e20635dd.tar.gz
python3-dbus: re-add recipe with latest patches and add ptest
The python3-dbus package was removed in (dac933e). While the upstream project isn't active, other distributions (e.g. Fedora, Debian, etc) continue to offer the package and apply patches to resolve reported issues. While other packages offer similar functionality (e.g. dasbus), they are not drop in replacements and the general dbus functionality works out of the box. The python package has accomplished it's goal of providing useful functionality, and the proposal is to continue to have it available in meta-python for use. Signed-off-by: Derek Straka <derek@asterius.io> Signed-off-by: Khem Raj <raj.khem@gmail.com>
Diffstat (limited to 'meta-python/recipes-devtools/python/python3-pydbus/0002-Support-asynchronous-calls-58.patch')
-rw-r--r--meta-python/recipes-devtools/python/python3-pydbus/0002-Support-asynchronous-calls-58.patch206
1 files changed, 206 insertions, 0 deletions
diff --git a/meta-python/recipes-devtools/python/python3-pydbus/0002-Support-asynchronous-calls-58.patch b/meta-python/recipes-devtools/python/python3-pydbus/0002-Support-asynchronous-calls-58.patch
new file mode 100644
index 0000000000..b3c57edade
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-pydbus/0002-Support-asynchronous-calls-58.patch
@@ -0,0 +1,206 @@
1From 31d6dd7893a5e1bb9eb14bfcee861a5b62f64960 Mon Sep 17 00:00:00 2001
2From: Vendula Poncova <vponcova@redhat.com>
3Date: Thu, 27 Jul 2017 18:41:29 +0200
4Subject: [PATCH 2/3] Support asynchronous calls (#58)
5
6Added support for asynchronous calls of methods. A method is called
7synchronously unless its callback parameter is specified. A callback
8is a function f(*args, returned=None, error=None), where args is
9callback_args specified in the method call, returned is a return
10value of the method and error is an exception raised by the method.
11
12Example of an asynchronous call:
13
14def func(x, y, returned=None, error=None):
15 pass
16
17proxy.Method(a, b, callback=func, callback_args=(x, y))
18
19Adapted from Fedora [https://src.fedoraproject.org/cgit/rpms/python-pydbus.git/]
20
21Upstream-Status: Inactive-Upstream (Last release 12/18/2016; Last commit 05/6/2018)
22
23Signed-off-by: Derek Straka <derek@asterius.io>
24---
25 doc/tutorial.rst | 11 ++++++++-
26 pydbus/proxy_method.py | 44 ++++++++++++++++++++++++++++++-----
27 tests/publish_async.py | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++
28 tests/run.sh | 1 +
29 4 files changed, 112 insertions(+), 7 deletions(-)
30 create mode 100644 tests/publish_async.py
31
32diff --git a/doc/tutorial.rst b/doc/tutorial.rst
33index 7474de3..b8479cf 100644
34--- a/doc/tutorial.rst
35+++ b/doc/tutorial.rst
36@@ -84,7 +84,8 @@ All objects have methods, properties and signals.
37 Setting up an event loop
38 ========================
39
40-To handle signals emitted by exported objects, or to export your own objects, you need to setup an event loop.
41+To handle signals emitted by exported objects, to asynchronously call methods
42+or to export your own objects, you need to setup an event loop.
43
44 The only main loop supported by ``pydbus`` is GLib.MainLoop.
45
46@@ -156,6 +157,14 @@ To call a method::
47
48 dev.Disconnect()
49
50+To asynchronously call a method::
51+
52+ def print_result(returned=None, error=None):
53+ print(returned, error)
54+
55+ dev.GetAppliedConnection(0, callback=print_result)
56+ loop.run()
57+
58 To read a property::
59
60 print(dev.Autoconnect)
61diff --git a/pydbus/proxy_method.py b/pydbus/proxy_method.py
62index 3e6e6ee..442fe07 100644
63--- a/pydbus/proxy_method.py
64+++ b/pydbus/proxy_method.py
65@@ -65,15 +65,34 @@ class ProxyMethod(object):
66
67 # Python 2 sux
68 for kwarg in kwargs:
69- if kwarg not in ("timeout",):
70+ if kwarg not in ("timeout", "callback", "callback_args"):
71 raise TypeError(self.__qualname__ + " got an unexpected keyword argument '{}'".format(kwarg))
72 timeout = kwargs.get("timeout", None)
73+ callback = kwargs.get("callback", None)
74+ callback_args = kwargs.get("callback_args", tuple())
75+
76+ call_args = (
77+ instance._bus_name,
78+ instance._path,
79+ self._iface_name,
80+ self.__name__,
81+ GLib.Variant(self._sinargs, args),
82+ GLib.VariantType.new(self._soutargs),
83+ 0,
84+ timeout_to_glib(timeout),
85+ None
86+ )
87+
88+ if callback:
89+ call_args += (self._finish_async_call, (callback, callback_args))
90+ instance._bus.con.call(*call_args)
91+ return None
92+ else:
93+ ret = instance._bus.con.call_sync(*call_args)
94+ return self._unpack_return(ret)
95
96- ret = instance._bus.con.call_sync(
97- instance._bus_name, instance._path,
98- self._iface_name, self.__name__, GLib.Variant(self._sinargs, args), GLib.VariantType.new(self._soutargs),
99- 0, timeout_to_glib(timeout), None).unpack()
100-
101+ def _unpack_return(self, values):
102+ ret = values.unpack()
103 if len(self._outargs) == 0:
104 return None
105 elif len(self._outargs) == 1:
106@@ -81,6 +100,19 @@ class ProxyMethod(object):
107 else:
108 return ret
109
110+ def _finish_async_call(self, source, result, user_data):
111+ error = None
112+ return_args = None
113+
114+ try:
115+ ret = source.call_finish(result)
116+ return_args = self._unpack_return(ret)
117+ except Exception as err:
118+ error = err
119+
120+ callback, callback_args = user_data
121+ callback(*callback_args, returned=return_args, error=error)
122+
123 def __get__(self, instance, owner):
124 if instance is None:
125 return self
126diff --git a/tests/publish_async.py b/tests/publish_async.py
127new file mode 100644
128index 0000000..3f79b62
129--- /dev/null
130+++ b/tests/publish_async.py
131@@ -0,0 +1,63 @@
132+from pydbus import SessionBus
133+from gi.repository import GLib
134+from threading import Thread
135+import sys
136+
137+done = 0
138+loop = GLib.MainLoop()
139+
140+class TestObject(object):
141+ '''
142+<node>
143+ <interface name='net.lew21.pydbus.tests.publish_async'>
144+ <method name='HelloWorld'>
145+ <arg type='i' name='x' direction='in'/>
146+ <arg type='s' name='response' direction='out'/>
147+ </method>
148+ </interface>
149+</node>
150+ '''
151+ def __init__(self, id):
152+ self.id = id
153+
154+ def HelloWorld(self, x):
155+ res = self.id + ": " + str(x)
156+ print(res)
157+ return res
158+
159+bus = SessionBus()
160+
161+with bus.publish("net.lew21.pydbus.tests.publish_async", TestObject("Obj")):
162+ remote = bus.get("net.lew21.pydbus.tests.publish_async")
163+
164+ def callback(x, returned=None, error=None):
165+ print("asyn: " + returned)
166+ assert (returned is not None)
167+ assert(error is None)
168+ assert(x == int(returned.split()[1]))
169+
170+ global done
171+ done += 1
172+ if done == 3:
173+ loop.quit()
174+
175+ def t1_func():
176+ remote.HelloWorld(1, callback=callback, callback_args=(1,))
177+ remote.HelloWorld(2, callback=callback, callback_args=(2,))
178+ print("sync: " + remote.HelloWorld(3))
179+ remote.HelloWorld(4, callback=callback, callback_args=(4,))
180+
181+ t1 = Thread(None, t1_func)
182+ t1.daemon = True
183+
184+ def handle_timeout():
185+ print("ERROR: Timeout.")
186+ sys.exit(1)
187+
188+ GLib.timeout_add_seconds(2, handle_timeout)
189+
190+ t1.start()
191+
192+ loop.run()
193+
194+ t1.join()
195diff --git a/tests/run.sh b/tests/run.sh
196index 8d93644..271c58a 100755
197--- a/tests/run.sh
198+++ b/tests/run.sh
199@@ -15,4 +15,5 @@ then
200 "$PYTHON" $TESTS_DIR/publish.py
201 "$PYTHON" $TESTS_DIR/publish_properties.py
202 "$PYTHON" $TESTS_DIR/publish_multiface.py
203+ "$PYTHON" $TESTS_DIR/publish_async.py
204 fi
205--
2062.13.5