dbus-fast 2.44.6__cp313-cp313-manylinux_2_36_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of dbus-fast might be problematic. Click here for more details.
- dbus_fast/__init__.py +82 -0
- dbus_fast/__version__.py +10 -0
- dbus_fast/_private/__init__.py +1 -0
- dbus_fast/_private/_cython_compat.py +14 -0
- dbus_fast/_private/address.cpython-313-x86_64-linux-gnu.so +0 -0
- dbus_fast/_private/address.pxd +15 -0
- dbus_fast/_private/address.py +117 -0
- dbus_fast/_private/constants.py +20 -0
- dbus_fast/_private/marshaller.cpython-313-x86_64-linux-gnu.so +0 -0
- dbus_fast/_private/marshaller.pxd +110 -0
- dbus_fast/_private/marshaller.py +228 -0
- dbus_fast/_private/unmarshaller.cpython-313-x86_64-linux-gnu.so +0 -0
- dbus_fast/_private/unmarshaller.pxd +261 -0
- dbus_fast/_private/unmarshaller.py +902 -0
- dbus_fast/_private/util.py +176 -0
- dbus_fast/aio/__init__.py +5 -0
- dbus_fast/aio/message_bus.py +578 -0
- dbus_fast/aio/message_reader.cpython-313-x86_64-linux-gnu.so +0 -0
- dbus_fast/aio/message_reader.pxd +13 -0
- dbus_fast/aio/message_reader.py +49 -0
- dbus_fast/aio/proxy_object.py +207 -0
- dbus_fast/auth.py +126 -0
- dbus_fast/constants.py +152 -0
- dbus_fast/errors.py +84 -0
- dbus_fast/glib/__init__.py +3 -0
- dbus_fast/glib/message_bus.py +515 -0
- dbus_fast/glib/proxy_object.py +319 -0
- dbus_fast/introspection.py +683 -0
- dbus_fast/message.cpython-313-x86_64-linux-gnu.so +0 -0
- dbus_fast/message.pxd +76 -0
- dbus_fast/message.py +387 -0
- dbus_fast/message_bus.cpython-313-x86_64-linux-gnu.so +0 -0
- dbus_fast/message_bus.pxd +75 -0
- dbus_fast/message_bus.py +1310 -0
- dbus_fast/proxy_object.py +358 -0
- dbus_fast/py.typed +0 -0
- dbus_fast/send_reply.py +61 -0
- dbus_fast/service.cpython-313-x86_64-linux-gnu.so +0 -0
- dbus_fast/service.pxd +50 -0
- dbus_fast/service.py +682 -0
- dbus_fast/signature.cpython-313-x86_64-linux-gnu.so +0 -0
- dbus_fast/signature.pxd +31 -0
- dbus_fast/signature.py +481 -0
- dbus_fast/unpack.cpython-313-x86_64-linux-gnu.so +0 -0
- dbus_fast/unpack.pxd +13 -0
- dbus_fast/unpack.py +24 -0
- dbus_fast/validators.py +199 -0
- dbus_fast-2.44.6.dist-info/METADATA +263 -0
- dbus_fast-2.44.6.dist-info/RECORD +51 -0
- dbus_fast-2.44.6.dist-info/WHEEL +4 -0
- dbus_fast-2.44.6.dist-info/licenses/LICENSE +22 -0
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
import xml.etree.ElementTree as ET
|
|
2
|
+
from typing import Union
|
|
3
|
+
|
|
4
|
+
from .. import introspection as intr
|
|
5
|
+
from ..constants import ErrorType
|
|
6
|
+
from ..errors import DBusError
|
|
7
|
+
from ..message import Message
|
|
8
|
+
from ..message_bus import BaseMessageBus
|
|
9
|
+
from ..proxy_object import BaseProxyInterface, BaseProxyObject
|
|
10
|
+
from ..signature import Variant
|
|
11
|
+
from ..unpack import unpack_variants as unpack
|
|
12
|
+
|
|
13
|
+
# glib is optional
|
|
14
|
+
try:
|
|
15
|
+
from gi.repository import GLib
|
|
16
|
+
except ImportError:
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ProxyInterface(BaseProxyInterface):
|
|
21
|
+
"""A class representing a proxy to an interface exported on the bus by
|
|
22
|
+
another client for the GLib :class:`MessageBus <dbus_fast.glib.MessageBus>`
|
|
23
|
+
implementation.
|
|
24
|
+
|
|
25
|
+
This class is not meant to be constructed directly by the user. Use
|
|
26
|
+
:func:`ProxyObject.get_interface()
|
|
27
|
+
<dbus_fast.glib.ProxyObject.get_interface>` on a GLib proxy
|
|
28
|
+
object to get a proxy interface.
|
|
29
|
+
|
|
30
|
+
This class exposes methods to call DBus methods, listen to signals, and get
|
|
31
|
+
and set properties on the interface that are created dynamically based on
|
|
32
|
+
the introspection data passed to the proxy object that made this proxy
|
|
33
|
+
interface.
|
|
34
|
+
|
|
35
|
+
A *method call* takes this form:
|
|
36
|
+
|
|
37
|
+
.. code-block:: python3
|
|
38
|
+
|
|
39
|
+
def callback(error: Exception, result: list(Any)):
|
|
40
|
+
pass
|
|
41
|
+
|
|
42
|
+
interface.call_[METHOD](*args, callback)
|
|
43
|
+
result = interface.call_[METHOD]_sync(*args)
|
|
44
|
+
|
|
45
|
+
Where ``METHOD`` is the name of the method converted to snake case.
|
|
46
|
+
|
|
47
|
+
To call a method, provide ``*args`` that correspond to the *in args* of the
|
|
48
|
+
introspection method definition.
|
|
49
|
+
|
|
50
|
+
To *asynchronously* call a method, provide a callback that takes an error
|
|
51
|
+
as the first argument and a list as the second argument. If the call
|
|
52
|
+
completed successfully, ``error`` will be :class:`None`. If the service
|
|
53
|
+
returns an error, it will be a :class:`DBusError <dbus_fast.DBusError>`
|
|
54
|
+
with information about the error returned from the bus. The result will be
|
|
55
|
+
a list of values that correspond to the *out args* of the introspection
|
|
56
|
+
method definition.
|
|
57
|
+
|
|
58
|
+
To *synchronously* call a method, use the ``call_[METHOD]_sync()`` form.
|
|
59
|
+
The ``result`` corresponds to the *out arg* of the introspection method
|
|
60
|
+
definition. If the method has more than one otu arg, they are returned
|
|
61
|
+
within a :class:`list`.
|
|
62
|
+
|
|
63
|
+
To *listen to a signal* use this form:
|
|
64
|
+
|
|
65
|
+
.. code-block:: python3
|
|
66
|
+
|
|
67
|
+
interface.on_[SIGNAL](callback)
|
|
68
|
+
|
|
69
|
+
To *stop listening to a signal* use this form:
|
|
70
|
+
|
|
71
|
+
.. code-block:: python3
|
|
72
|
+
|
|
73
|
+
interface.off_[SIGNAL](callback)
|
|
74
|
+
|
|
75
|
+
Where ``SIGNAL`` is the name of the signal converted to snake case.
|
|
76
|
+
|
|
77
|
+
DBus signals are exposed with an event-callback interface. The provided
|
|
78
|
+
``callback`` will be called when the signal is emitted with arguments that
|
|
79
|
+
correspond to the *out args* of the interface signal definition.
|
|
80
|
+
|
|
81
|
+
To *get or set a property* use this form:
|
|
82
|
+
|
|
83
|
+
.. code-block:: python3
|
|
84
|
+
|
|
85
|
+
def get_callback(error: Exception, value: Any):
|
|
86
|
+
pass
|
|
87
|
+
|
|
88
|
+
def set_callback(error: Exception)
|
|
89
|
+
pass
|
|
90
|
+
|
|
91
|
+
interface.get_[PROPERTY](get_callback)
|
|
92
|
+
value: Any = interface.get_[PROPERTY]_sync()
|
|
93
|
+
|
|
94
|
+
interface.set_[PROPERTY](set_callback)
|
|
95
|
+
interface.set_[PROPERTY]_sync(value)
|
|
96
|
+
|
|
97
|
+
Where ``PROPERTY`` is the name of the property converted to snake case.
|
|
98
|
+
|
|
99
|
+
The ``value`` must correspond to the type of the property in the interface
|
|
100
|
+
definition.
|
|
101
|
+
|
|
102
|
+
To asynchronously get or set a property, provide a callback that takes an
|
|
103
|
+
:class:`Exception` as the first argument. If the call completed
|
|
104
|
+
successfully, ``error`` will be :class:`None`. If the service returns an
|
|
105
|
+
error, it will be a :class:`DBusError <dbus_fast.DBusError>` with
|
|
106
|
+
information about the error returned from the bus.
|
|
107
|
+
|
|
108
|
+
If the service returns an error for a synchronous DBus call, a
|
|
109
|
+
:class:`DBusError <dbus_fast.DBusError>` will be raised with information
|
|
110
|
+
about the error.
|
|
111
|
+
"""
|
|
112
|
+
|
|
113
|
+
def _add_method(self, intr_method):
|
|
114
|
+
in_len = len(intr_method.in_args)
|
|
115
|
+
out_len = len(intr_method.out_args)
|
|
116
|
+
|
|
117
|
+
def method_fn(*args, unpack_variants: bool = False):
|
|
118
|
+
if len(args) != in_len + 1:
|
|
119
|
+
raise TypeError(
|
|
120
|
+
f"method {intr_method.name} expects {in_len} arguments and a callback (got {len(args)} args)"
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
args = list(args)
|
|
124
|
+
# TODO type check: this callback takes two parameters
|
|
125
|
+
# (MessageBus.check_callback(cb))
|
|
126
|
+
callback = args.pop()
|
|
127
|
+
|
|
128
|
+
def call_notify(msg, err):
|
|
129
|
+
if err:
|
|
130
|
+
callback([], err)
|
|
131
|
+
return
|
|
132
|
+
|
|
133
|
+
try:
|
|
134
|
+
BaseProxyInterface._check_method_return(
|
|
135
|
+
msg, intr_method.out_signature
|
|
136
|
+
)
|
|
137
|
+
except DBusError as e:
|
|
138
|
+
err = e
|
|
139
|
+
|
|
140
|
+
if unpack_variants:
|
|
141
|
+
callback(unpack(msg.body), err)
|
|
142
|
+
else:
|
|
143
|
+
callback(msg.body, err)
|
|
144
|
+
|
|
145
|
+
self.bus.call(
|
|
146
|
+
Message(
|
|
147
|
+
destination=self.bus_name,
|
|
148
|
+
path=self.path,
|
|
149
|
+
interface=self.introspection.name,
|
|
150
|
+
member=intr_method.name,
|
|
151
|
+
signature=intr_method.in_signature,
|
|
152
|
+
body=list(args),
|
|
153
|
+
),
|
|
154
|
+
call_notify,
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
def method_fn_sync(*args, unpack_variants: bool = False):
|
|
158
|
+
main = GLib.MainLoop()
|
|
159
|
+
call_error = None
|
|
160
|
+
call_body = None
|
|
161
|
+
|
|
162
|
+
def callback(body, err):
|
|
163
|
+
nonlocal call_error
|
|
164
|
+
nonlocal call_body
|
|
165
|
+
call_error = err
|
|
166
|
+
call_body = body
|
|
167
|
+
main.quit()
|
|
168
|
+
|
|
169
|
+
method_fn(*args, callback)
|
|
170
|
+
|
|
171
|
+
main.run()
|
|
172
|
+
|
|
173
|
+
if call_error:
|
|
174
|
+
raise call_error
|
|
175
|
+
|
|
176
|
+
if not out_len:
|
|
177
|
+
return None
|
|
178
|
+
|
|
179
|
+
if unpack_variants:
|
|
180
|
+
call_body = unpack(call_body)
|
|
181
|
+
|
|
182
|
+
if out_len == 1:
|
|
183
|
+
return call_body[0]
|
|
184
|
+
return call_body
|
|
185
|
+
|
|
186
|
+
method_name = f"call_{BaseProxyInterface._to_snake_case(intr_method.name)}"
|
|
187
|
+
method_name_sync = f"{method_name}_sync"
|
|
188
|
+
|
|
189
|
+
setattr(self, method_name, method_fn)
|
|
190
|
+
setattr(self, method_name_sync, method_fn_sync)
|
|
191
|
+
|
|
192
|
+
def _add_property(self, intr_property):
|
|
193
|
+
def property_getter(callback, *, unpack_variants: bool = False):
|
|
194
|
+
def call_notify(msg, err):
|
|
195
|
+
if err:
|
|
196
|
+
callback(None, err)
|
|
197
|
+
return
|
|
198
|
+
|
|
199
|
+
try:
|
|
200
|
+
BaseProxyInterface._check_method_return(msg)
|
|
201
|
+
except Exception as e:
|
|
202
|
+
callback(None, e)
|
|
203
|
+
return
|
|
204
|
+
|
|
205
|
+
variant = msg.body[0]
|
|
206
|
+
if variant.signature != intr_property.signature:
|
|
207
|
+
err = DBusError(
|
|
208
|
+
ErrorType.CLIENT_ERROR,
|
|
209
|
+
'property returned unexpected signature "{variant.signature}"',
|
|
210
|
+
msg,
|
|
211
|
+
)
|
|
212
|
+
callback(None, err)
|
|
213
|
+
return
|
|
214
|
+
if unpack_variants:
|
|
215
|
+
callback(unpack(variant.value), None)
|
|
216
|
+
else:
|
|
217
|
+
callback(variant.value, None)
|
|
218
|
+
|
|
219
|
+
self.bus.call(
|
|
220
|
+
Message(
|
|
221
|
+
destination=self.bus_name,
|
|
222
|
+
path=self.path,
|
|
223
|
+
interface="org.freedesktop.DBus.Properties",
|
|
224
|
+
member="Get",
|
|
225
|
+
signature="ss",
|
|
226
|
+
body=[self.introspection.name, intr_property.name],
|
|
227
|
+
),
|
|
228
|
+
call_notify,
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
def property_getter_sync(*, unpack_variants: bool = False):
|
|
232
|
+
property_value = None
|
|
233
|
+
reply_error = None
|
|
234
|
+
|
|
235
|
+
main = GLib.MainLoop()
|
|
236
|
+
|
|
237
|
+
def callback(value, err):
|
|
238
|
+
nonlocal property_value
|
|
239
|
+
nonlocal reply_error
|
|
240
|
+
property_value = value
|
|
241
|
+
reply_error = err
|
|
242
|
+
main.quit()
|
|
243
|
+
|
|
244
|
+
property_getter(callback)
|
|
245
|
+
main.run()
|
|
246
|
+
if reply_error:
|
|
247
|
+
raise reply_error
|
|
248
|
+
if unpack_variants:
|
|
249
|
+
return unpack(property_value)
|
|
250
|
+
return property_value
|
|
251
|
+
|
|
252
|
+
def property_setter(value, callback):
|
|
253
|
+
def call_notify(msg, err):
|
|
254
|
+
if err:
|
|
255
|
+
callback(None, err)
|
|
256
|
+
return None
|
|
257
|
+
try:
|
|
258
|
+
BaseProxyInterface._check_method_return(msg)
|
|
259
|
+
except Exception as e:
|
|
260
|
+
callback(None, e)
|
|
261
|
+
return None
|
|
262
|
+
|
|
263
|
+
return callback(None, None)
|
|
264
|
+
|
|
265
|
+
variant = Variant(intr_property.signature, value)
|
|
266
|
+
self.bus.call(
|
|
267
|
+
Message(
|
|
268
|
+
destination=self.bus_name,
|
|
269
|
+
path=self.path,
|
|
270
|
+
interface="org.freedesktop.DBus.Properties",
|
|
271
|
+
member="Set",
|
|
272
|
+
signature="ssv",
|
|
273
|
+
body=[self.introspection.name, intr_property.name, variant],
|
|
274
|
+
),
|
|
275
|
+
call_notify,
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
def property_setter_sync(val):
|
|
279
|
+
reply_error = None
|
|
280
|
+
|
|
281
|
+
main = GLib.MainLoop()
|
|
282
|
+
|
|
283
|
+
def callback(value, err):
|
|
284
|
+
nonlocal reply_error
|
|
285
|
+
reply_error = err
|
|
286
|
+
main.quit()
|
|
287
|
+
|
|
288
|
+
property_setter(val, callback)
|
|
289
|
+
main.run()
|
|
290
|
+
if reply_error:
|
|
291
|
+
raise reply_error
|
|
292
|
+
|
|
293
|
+
snake_case = super()._to_snake_case(intr_property.name)
|
|
294
|
+
setattr(self, f"get_{snake_case}", property_getter)
|
|
295
|
+
setattr(self, f"get_{snake_case}_sync", property_getter_sync)
|
|
296
|
+
setattr(self, f"set_{snake_case}", property_setter)
|
|
297
|
+
setattr(self, f"set_{snake_case}_sync", property_setter_sync)
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
class ProxyObject(BaseProxyObject):
|
|
301
|
+
"""The proxy object implementation for the asyncio :class:`MessageBus <dbus_fast.aio.MessageBus>`.
|
|
302
|
+
|
|
303
|
+
For more information, see the :class:`BaseProxyObject <dbus_fast.proxy_object.BaseProxyObject>`.
|
|
304
|
+
"""
|
|
305
|
+
|
|
306
|
+
def __init__(
|
|
307
|
+
self,
|
|
308
|
+
bus_name: str,
|
|
309
|
+
path: str,
|
|
310
|
+
introspection: Union[intr.Node, str, ET.Element],
|
|
311
|
+
bus: BaseMessageBus,
|
|
312
|
+
):
|
|
313
|
+
super().__init__(bus_name, path, introspection, bus, ProxyInterface)
|
|
314
|
+
|
|
315
|
+
def get_interface(self, name: str) -> ProxyInterface:
|
|
316
|
+
return super().get_interface(name)
|
|
317
|
+
|
|
318
|
+
def get_children(self) -> list["ProxyObject"]:
|
|
319
|
+
return super().get_children()
|