dbus-fast 3.1.2__cp310-cp310-macosx_11_0_arm64.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.
- 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-310-darwin.so +0 -0
- dbus_fast/_private/address.pxd +15 -0
- dbus_fast/_private/address.py +119 -0
- dbus_fast/_private/constants.py +20 -0
- dbus_fast/_private/marshaller.cpython-310-darwin.so +0 -0
- dbus_fast/_private/marshaller.pxd +110 -0
- dbus_fast/_private/marshaller.py +231 -0
- dbus_fast/_private/unmarshaller.cpython-310-darwin.so +0 -0
- dbus_fast/_private/unmarshaller.pxd +261 -0
- dbus_fast/_private/unmarshaller.py +904 -0
- dbus_fast/_private/util.py +177 -0
- dbus_fast/aio/__init__.py +5 -0
- dbus_fast/aio/message_bus.py +578 -0
- dbus_fast/aio/message_reader.cpython-310-darwin.so +0 -0
- dbus_fast/aio/message_reader.pxd +13 -0
- dbus_fast/aio/message_reader.py +51 -0
- dbus_fast/aio/proxy_object.py +208 -0
- dbus_fast/auth.py +125 -0
- dbus_fast/constants.py +152 -0
- dbus_fast/errors.py +81 -0
- dbus_fast/glib/__init__.py +3 -0
- dbus_fast/glib/message_bus.py +513 -0
- dbus_fast/glib/proxy_object.py +318 -0
- dbus_fast/introspection.py +686 -0
- dbus_fast/message.cpython-310-darwin.so +0 -0
- dbus_fast/message.pxd +76 -0
- dbus_fast/message.py +389 -0
- dbus_fast/message_bus.cpython-310-darwin.so +0 -0
- dbus_fast/message_bus.pxd +75 -0
- dbus_fast/message_bus.py +1332 -0
- dbus_fast/proxy_object.py +357 -0
- dbus_fast/py.typed +0 -0
- dbus_fast/send_reply.py +61 -0
- dbus_fast/service.cpython-310-darwin.so +0 -0
- dbus_fast/service.pxd +50 -0
- dbus_fast/service.py +727 -0
- dbus_fast/signature.cpython-310-darwin.so +0 -0
- dbus_fast/signature.pxd +31 -0
- dbus_fast/signature.py +484 -0
- dbus_fast/unpack.cpython-310-darwin.so +0 -0
- dbus_fast/unpack.pxd +13 -0
- dbus_fast/unpack.py +28 -0
- dbus_fast/validators.py +199 -0
- dbus_fast-3.1.2.dist-info/METADATA +262 -0
- dbus_fast-3.1.2.dist-info/RECORD +51 -0
- dbus_fast-3.1.2.dist-info/WHEEL +6 -0
- dbus_fast-3.1.2.dist-info/licenses/LICENSE +22 -0
|
@@ -0,0 +1,513 @@
|
|
|
1
|
+
import io
|
|
2
|
+
import logging
|
|
3
|
+
import traceback
|
|
4
|
+
from collections.abc import Callable
|
|
5
|
+
|
|
6
|
+
from .. import introspection as intr
|
|
7
|
+
from .._private.unmarshaller import Unmarshaller
|
|
8
|
+
from ..auth import Authenticator, AuthExternal
|
|
9
|
+
from ..constants import (
|
|
10
|
+
BusType,
|
|
11
|
+
MessageFlag,
|
|
12
|
+
MessageType,
|
|
13
|
+
NameFlag,
|
|
14
|
+
ReleaseNameReply,
|
|
15
|
+
RequestNameReply,
|
|
16
|
+
)
|
|
17
|
+
from ..errors import AuthError
|
|
18
|
+
from ..message import Message
|
|
19
|
+
from ..message_bus import BaseMessageBus
|
|
20
|
+
from .proxy_object import ProxyObject
|
|
21
|
+
|
|
22
|
+
_LOGGER = logging.getLogger(__name__)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# glib is optional
|
|
26
|
+
_import_error = None
|
|
27
|
+
try:
|
|
28
|
+
from gi.repository import GLib
|
|
29
|
+
|
|
30
|
+
_GLibSource = GLib.Source
|
|
31
|
+
except ImportError as e:
|
|
32
|
+
_import_error = e
|
|
33
|
+
|
|
34
|
+
class _GLibSource:
|
|
35
|
+
pass
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class _MessageSource(_GLibSource):
|
|
39
|
+
def __init__(self, bus):
|
|
40
|
+
self.unmarshaller = None
|
|
41
|
+
self.bus = bus
|
|
42
|
+
|
|
43
|
+
def prepare(self):
|
|
44
|
+
return (False, -1)
|
|
45
|
+
|
|
46
|
+
def check(self):
|
|
47
|
+
return False
|
|
48
|
+
|
|
49
|
+
def dispatch(self, callback, user_data):
|
|
50
|
+
try:
|
|
51
|
+
while self.bus._stream.readable():
|
|
52
|
+
if not self.unmarshaller:
|
|
53
|
+
self.unmarshaller = Unmarshaller(self.bus._stream)
|
|
54
|
+
|
|
55
|
+
message = self.unmarshaller.unmarshall()
|
|
56
|
+
if message:
|
|
57
|
+
callback(message)
|
|
58
|
+
self.unmarshaller = None
|
|
59
|
+
else:
|
|
60
|
+
break
|
|
61
|
+
except Exception as e:
|
|
62
|
+
self.bus.disconnect()
|
|
63
|
+
self.bus._finalize(e)
|
|
64
|
+
return GLib.SOURCE_REMOVE
|
|
65
|
+
|
|
66
|
+
return GLib.SOURCE_CONTINUE
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class _MessageWritableSource(_GLibSource):
|
|
70
|
+
def __init__(self, bus):
|
|
71
|
+
self.bus = bus
|
|
72
|
+
self.buf = b""
|
|
73
|
+
self.message_stream = None
|
|
74
|
+
self.chunk_size = 128
|
|
75
|
+
|
|
76
|
+
def prepare(self):
|
|
77
|
+
return (False, -1)
|
|
78
|
+
|
|
79
|
+
def check(self):
|
|
80
|
+
return False
|
|
81
|
+
|
|
82
|
+
def dispatch(self, callback, user_data):
|
|
83
|
+
try:
|
|
84
|
+
if self.buf:
|
|
85
|
+
self.bus._stream.write(self.buf)
|
|
86
|
+
self.buf = b""
|
|
87
|
+
|
|
88
|
+
if self.message_stream:
|
|
89
|
+
while True:
|
|
90
|
+
self.buf = self.message_stream.read(self.chunk_size)
|
|
91
|
+
if self.buf == b"":
|
|
92
|
+
break
|
|
93
|
+
self.bus._stream.write(self.buf)
|
|
94
|
+
if len(self.buf) < self.chunk_size:
|
|
95
|
+
self.buf = b""
|
|
96
|
+
break
|
|
97
|
+
self.buf = b""
|
|
98
|
+
|
|
99
|
+
self.bus._stream.flush()
|
|
100
|
+
|
|
101
|
+
if not self.bus._buffered_messages:
|
|
102
|
+
return GLib.SOURCE_REMOVE
|
|
103
|
+
message = self.bus._buffered_messages.pop(0)
|
|
104
|
+
self.message_stream = io.BytesIO(message._marshall(False))
|
|
105
|
+
return GLib.SOURCE_CONTINUE
|
|
106
|
+
except BlockingIOError:
|
|
107
|
+
return GLib.SOURCE_CONTINUE
|
|
108
|
+
except Exception as e:
|
|
109
|
+
self.bus._finalize(e)
|
|
110
|
+
return GLib.SOURCE_REMOVE
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class _AuthLineSource(_GLibSource):
|
|
114
|
+
def __init__(self, stream):
|
|
115
|
+
self.stream = stream
|
|
116
|
+
self.buf = b""
|
|
117
|
+
|
|
118
|
+
def prepare(self):
|
|
119
|
+
return (False, -1)
|
|
120
|
+
|
|
121
|
+
def check(self):
|
|
122
|
+
return False
|
|
123
|
+
|
|
124
|
+
def dispatch(self, callback, user_data):
|
|
125
|
+
self.buf += self.stream.read()
|
|
126
|
+
if self.buf[-2:] == b"\r\n":
|
|
127
|
+
resp = callback(self.buf.decode()[:-2])
|
|
128
|
+
if resp:
|
|
129
|
+
return GLib.SOURCE_REMOVE
|
|
130
|
+
|
|
131
|
+
return GLib.SOURCE_CONTINUE
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
class MessageBus(BaseMessageBus):
|
|
135
|
+
"""The message bus implementation for use with the GLib main loop.
|
|
136
|
+
|
|
137
|
+
The message bus class is the entry point into all the features of the
|
|
138
|
+
library. It sets up a connection to the DBus daemon and exposes an
|
|
139
|
+
interface to send and receive messages and expose services.
|
|
140
|
+
|
|
141
|
+
You must call :func:`connect() <dbus_fast.glib.MessageBus.connect>` or
|
|
142
|
+
:func:`connect_sync() <dbus_fast.glib.MessageBus.connect_sync>` before
|
|
143
|
+
using this message bus.
|
|
144
|
+
|
|
145
|
+
:param bus_type: The type of bus to connect to. Affects the search path for
|
|
146
|
+
the bus address.
|
|
147
|
+
:type bus_type: :class:`BusType <dbus_fast.BusType>`
|
|
148
|
+
:param bus_address: A specific bus address to connect to. Should not be
|
|
149
|
+
used under normal circumstances.
|
|
150
|
+
:param auth: The authenticator to use, defaults to an instance of
|
|
151
|
+
:class:`AuthExternal <dbus_fast.auth.AuthExternal>`.
|
|
152
|
+
:type auth: :class:`Authenticator <dbus_fast.auth.Authenticator>`
|
|
153
|
+
|
|
154
|
+
:ivar connected: True if this message bus is expected to be able to send
|
|
155
|
+
and receive messages.
|
|
156
|
+
:vartype connected: bool
|
|
157
|
+
:ivar unique_name: The unique name of the message bus connection. It will
|
|
158
|
+
be :class:`None` until the message bus connects.
|
|
159
|
+
:vartype unique_name: str
|
|
160
|
+
"""
|
|
161
|
+
|
|
162
|
+
def __init__(
|
|
163
|
+
self,
|
|
164
|
+
bus_address: str | None = None,
|
|
165
|
+
bus_type: BusType = BusType.SESSION,
|
|
166
|
+
auth: Authenticator | None = None,
|
|
167
|
+
):
|
|
168
|
+
if _import_error:
|
|
169
|
+
raise _import_error
|
|
170
|
+
|
|
171
|
+
super().__init__(bus_address, bus_type, ProxyObject)
|
|
172
|
+
self._main_context = GLib.main_context_default()
|
|
173
|
+
# buffer messages until connect
|
|
174
|
+
self._buffered_messages = []
|
|
175
|
+
|
|
176
|
+
if auth is None:
|
|
177
|
+
self._auth = AuthExternal()
|
|
178
|
+
else:
|
|
179
|
+
self._auth = auth
|
|
180
|
+
|
|
181
|
+
def _on_message(self, msg: Message) -> None:
|
|
182
|
+
try:
|
|
183
|
+
self._process_message(msg)
|
|
184
|
+
except Exception as e:
|
|
185
|
+
_LOGGER.exception(
|
|
186
|
+
f"got unexpected error processing a message: {e}.\n{traceback.format_exc()}"
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
def connect(
|
|
190
|
+
self,
|
|
191
|
+
connect_notify: None
|
|
192
|
+
| (Callable[["MessageBus", Exception | None], None]) = None,
|
|
193
|
+
):
|
|
194
|
+
"""Connect this message bus to the DBus daemon.
|
|
195
|
+
|
|
196
|
+
This method or the synchronous version must be called before the
|
|
197
|
+
message bus can be used.
|
|
198
|
+
|
|
199
|
+
:param connect_notify: A callback that will be called with this message
|
|
200
|
+
bus. May return an :class:`Exception` on connection errors or
|
|
201
|
+
:class:`AuthError <dbus_fast.AuthError>` on authorization errors.
|
|
202
|
+
:type callback: :class:`Callable`
|
|
203
|
+
"""
|
|
204
|
+
|
|
205
|
+
def authenticate_notify(exc):
|
|
206
|
+
if exc is not None:
|
|
207
|
+
if connect_notify is not None:
|
|
208
|
+
connect_notify(None, exc)
|
|
209
|
+
return
|
|
210
|
+
self.message_source = _MessageSource(self)
|
|
211
|
+
self.message_source.set_callback(self._on_message)
|
|
212
|
+
self.message_source.attach(self._main_context)
|
|
213
|
+
|
|
214
|
+
self.writable_source = None
|
|
215
|
+
|
|
216
|
+
self.message_source.add_unix_fd(self._fd, GLib.IO_IN)
|
|
217
|
+
|
|
218
|
+
def on_hello(reply, err):
|
|
219
|
+
if err:
|
|
220
|
+
if connect_notify:
|
|
221
|
+
connect_notify(reply, err)
|
|
222
|
+
return
|
|
223
|
+
|
|
224
|
+
self.unique_name = reply.body[0]
|
|
225
|
+
|
|
226
|
+
for m in self._buffered_messages:
|
|
227
|
+
self.send(m)
|
|
228
|
+
|
|
229
|
+
if connect_notify:
|
|
230
|
+
connect_notify(self, err)
|
|
231
|
+
|
|
232
|
+
hello_msg = Message(
|
|
233
|
+
destination="org.freedesktop.DBus",
|
|
234
|
+
path="/org/freedesktop/DBus",
|
|
235
|
+
interface="org.freedesktop.DBus",
|
|
236
|
+
member="Hello",
|
|
237
|
+
serial=self.next_serial(),
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
self._method_return_handlers[hello_msg.serial] = on_hello
|
|
241
|
+
self._stream.write(hello_msg._marshall(False))
|
|
242
|
+
self._stream.flush()
|
|
243
|
+
|
|
244
|
+
self._authenticate(authenticate_notify)
|
|
245
|
+
|
|
246
|
+
def connect_sync(self) -> "MessageBus":
|
|
247
|
+
"""Connect this message bus to the DBus daemon.
|
|
248
|
+
|
|
249
|
+
This method or the asynchronous version must be called before the
|
|
250
|
+
message bus can be used.
|
|
251
|
+
|
|
252
|
+
:returns: This message bus for convenience.
|
|
253
|
+
:rtype: :class:`MessageBus <dbus_fast.glib.MessageBus>`
|
|
254
|
+
|
|
255
|
+
:raises:
|
|
256
|
+
- :class:`AuthError <dbus_fast.AuthError>` - If authorization to \
|
|
257
|
+
the DBus daemon failed.
|
|
258
|
+
- :class:`Exception` - If there was a connection error.
|
|
259
|
+
"""
|
|
260
|
+
main = GLib.MainLoop()
|
|
261
|
+
connection_error = None
|
|
262
|
+
|
|
263
|
+
def connect_notify(bus, err):
|
|
264
|
+
nonlocal connection_error
|
|
265
|
+
connection_error = err
|
|
266
|
+
main.quit()
|
|
267
|
+
|
|
268
|
+
self.connect(connect_notify)
|
|
269
|
+
main.run()
|
|
270
|
+
|
|
271
|
+
if connection_error:
|
|
272
|
+
raise connection_error
|
|
273
|
+
|
|
274
|
+
return self
|
|
275
|
+
|
|
276
|
+
def call(
|
|
277
|
+
self,
|
|
278
|
+
msg: Message,
|
|
279
|
+
reply_notify: None
|
|
280
|
+
| (Callable[[Message | None, Exception | None], None]) = None,
|
|
281
|
+
):
|
|
282
|
+
"""Send a method call and asynchronously wait for a reply from the DBus
|
|
283
|
+
daemon.
|
|
284
|
+
|
|
285
|
+
:param msg: The method call message to send.
|
|
286
|
+
:type msg: :class:`Message <dbus_fast.Message>`
|
|
287
|
+
:param reply_notify: A callback that will be called with the reply to
|
|
288
|
+
this message. May return an :class:`Exception` on connection errors.
|
|
289
|
+
:type reply_notify: Callable
|
|
290
|
+
"""
|
|
291
|
+
BaseMessageBus._check_callback_type(reply_notify)
|
|
292
|
+
self._call(msg, reply_notify)
|
|
293
|
+
|
|
294
|
+
def call_sync(self, msg: Message) -> Message | None:
|
|
295
|
+
"""Send a method call and synchronously wait for a reply from the DBus
|
|
296
|
+
daemon.
|
|
297
|
+
|
|
298
|
+
:param msg: The method call message to send.
|
|
299
|
+
:type msg: :class:`Message <dbus_fast.Message>`
|
|
300
|
+
|
|
301
|
+
:returns: A message in reply to the message sent. If the message does
|
|
302
|
+
not expect a reply based on the message flags or type, returns
|
|
303
|
+
``None`` immediately.
|
|
304
|
+
:rtype: :class:`Message <dbus_fast.Message>`
|
|
305
|
+
|
|
306
|
+
:raises:
|
|
307
|
+
- :class:`DBusError <dbus_fast.DBusError>` - If the service threw \
|
|
308
|
+
an error for the method call or returned an invalid result.
|
|
309
|
+
- :class:`Exception` - If a connection error occurred.
|
|
310
|
+
"""
|
|
311
|
+
if (
|
|
312
|
+
msg.flags & MessageFlag.NO_REPLY_EXPECTED
|
|
313
|
+
or msg.message_type is not MessageType.METHOD_CALL
|
|
314
|
+
):
|
|
315
|
+
self.send(msg)
|
|
316
|
+
return None
|
|
317
|
+
|
|
318
|
+
if not msg.serial:
|
|
319
|
+
msg.serial = self.next_serial()
|
|
320
|
+
|
|
321
|
+
main = GLib.MainLoop()
|
|
322
|
+
handler_reply = None
|
|
323
|
+
connection_error = None
|
|
324
|
+
|
|
325
|
+
def reply_handler(reply, err):
|
|
326
|
+
nonlocal handler_reply
|
|
327
|
+
nonlocal connection_error
|
|
328
|
+
|
|
329
|
+
handler_reply = reply
|
|
330
|
+
connection_error = err
|
|
331
|
+
|
|
332
|
+
main.quit()
|
|
333
|
+
|
|
334
|
+
self._method_return_handlers[msg.serial] = reply_handler
|
|
335
|
+
self.send(msg)
|
|
336
|
+
main.run()
|
|
337
|
+
|
|
338
|
+
if connection_error:
|
|
339
|
+
raise connection_error
|
|
340
|
+
|
|
341
|
+
return handler_reply
|
|
342
|
+
|
|
343
|
+
def introspect_sync(self, bus_name: str, path: str) -> intr.Node:
|
|
344
|
+
"""Get introspection data for the node at the given path from the given
|
|
345
|
+
bus name.
|
|
346
|
+
|
|
347
|
+
Calls the standard ``org.freedesktop.DBus.Introspectable.Introspect``
|
|
348
|
+
on the bus for the path.
|
|
349
|
+
|
|
350
|
+
:param bus_name: The name to introspect.
|
|
351
|
+
:type bus_name: str
|
|
352
|
+
:param path: The path to introspect.
|
|
353
|
+
:type path: str
|
|
354
|
+
|
|
355
|
+
:returns: The introspection data for the name at the path.
|
|
356
|
+
:rtype: :class:`Node <dbus_fast.introspection.Node>`
|
|
357
|
+
|
|
358
|
+
:raises:
|
|
359
|
+
- :class:`InvalidObjectPathError <dbus_fast.InvalidObjectPathError>` \
|
|
360
|
+
- If the given object path is not valid.
|
|
361
|
+
- :class:`InvalidBusNameError <dbus_fast.InvalidBusNameError>` - If \
|
|
362
|
+
the given bus name is not valid.
|
|
363
|
+
- :class:`DBusError <dbus_fast.DBusError>` - If the service threw \
|
|
364
|
+
an error for the method call or returned an invalid result.
|
|
365
|
+
- :class:`Exception` - If a connection error occurred.
|
|
366
|
+
"""
|
|
367
|
+
main = GLib.MainLoop()
|
|
368
|
+
request_result = None
|
|
369
|
+
request_error = None
|
|
370
|
+
|
|
371
|
+
def reply_notify(result, err):
|
|
372
|
+
nonlocal request_result
|
|
373
|
+
nonlocal request_error
|
|
374
|
+
|
|
375
|
+
request_result = result
|
|
376
|
+
request_error = err
|
|
377
|
+
|
|
378
|
+
main.quit()
|
|
379
|
+
|
|
380
|
+
super().introspect(bus_name, path, reply_notify)
|
|
381
|
+
main.run()
|
|
382
|
+
|
|
383
|
+
if request_error:
|
|
384
|
+
raise request_error
|
|
385
|
+
|
|
386
|
+
return request_result
|
|
387
|
+
|
|
388
|
+
def request_name_sync(
|
|
389
|
+
self, name: str, flags: NameFlag = NameFlag.NONE
|
|
390
|
+
) -> RequestNameReply:
|
|
391
|
+
"""Request that this message bus owns the given name.
|
|
392
|
+
|
|
393
|
+
:param name: The name to request.
|
|
394
|
+
:type name: str
|
|
395
|
+
:param flags: Name flags that affect the behavior of the name request.
|
|
396
|
+
:type flags: :class:`NameFlag <dbus_fast.NameFlag>`
|
|
397
|
+
|
|
398
|
+
:returns: The reply to the name request.
|
|
399
|
+
:rtype: :class:`RequestNameReply <dbus_fast.RequestNameReply>`
|
|
400
|
+
|
|
401
|
+
:raises:
|
|
402
|
+
- :class:`InvalidBusNameError <dbus_fast.InvalidBusNameError>` - If \
|
|
403
|
+
the given bus name is not valid.
|
|
404
|
+
- :class:`DBusError <dbus_fast.DBusError>` - If the service threw \
|
|
405
|
+
an error for the method call or returned an invalid result.
|
|
406
|
+
- :class:`Exception` - If a connection error occurred.
|
|
407
|
+
"""
|
|
408
|
+
main = GLib.MainLoop()
|
|
409
|
+
request_result = None
|
|
410
|
+
request_error = None
|
|
411
|
+
|
|
412
|
+
def reply_notify(result, err):
|
|
413
|
+
nonlocal request_result
|
|
414
|
+
nonlocal request_error
|
|
415
|
+
|
|
416
|
+
request_result = result
|
|
417
|
+
request_error = err
|
|
418
|
+
|
|
419
|
+
main.quit()
|
|
420
|
+
|
|
421
|
+
super().request_name(name, flags, reply_notify)
|
|
422
|
+
main.run()
|
|
423
|
+
|
|
424
|
+
if request_error:
|
|
425
|
+
raise request_error
|
|
426
|
+
|
|
427
|
+
return request_result
|
|
428
|
+
|
|
429
|
+
def release_name_sync(self, name: str) -> ReleaseNameReply:
|
|
430
|
+
"""Request that this message bus release the given name.
|
|
431
|
+
|
|
432
|
+
:param name: The name to release.
|
|
433
|
+
:type name: str
|
|
434
|
+
|
|
435
|
+
:returns: The reply to the release request.
|
|
436
|
+
:rtype: :class:`ReleaseNameReply <dbus_fast.ReleaseNameReply>`
|
|
437
|
+
|
|
438
|
+
:raises:
|
|
439
|
+
- :class:`InvalidBusNameError <dbus_fast.InvalidBusNameError>` - If \
|
|
440
|
+
the given bus name is not valid.
|
|
441
|
+
- :class:`DBusError <dbus_fast.DBusError>` - If the service threw \
|
|
442
|
+
an error for the method call or returned an invalid result.
|
|
443
|
+
- :class:`Exception` - If a connection error occurred.
|
|
444
|
+
"""
|
|
445
|
+
main = GLib.MainLoop()
|
|
446
|
+
release_result = None
|
|
447
|
+
release_error = None
|
|
448
|
+
|
|
449
|
+
def reply_notify(result, err):
|
|
450
|
+
nonlocal release_result
|
|
451
|
+
nonlocal release_error
|
|
452
|
+
|
|
453
|
+
release_result = result
|
|
454
|
+
release_error = err
|
|
455
|
+
|
|
456
|
+
main.quit()
|
|
457
|
+
|
|
458
|
+
super().release_name(name, reply_notify)
|
|
459
|
+
main.run()
|
|
460
|
+
|
|
461
|
+
if release_error:
|
|
462
|
+
raise release_error
|
|
463
|
+
|
|
464
|
+
return release_result
|
|
465
|
+
|
|
466
|
+
def send(self, msg: Message):
|
|
467
|
+
if not msg.serial:
|
|
468
|
+
msg.serial = self.next_serial()
|
|
469
|
+
|
|
470
|
+
self._buffered_messages.append(msg)
|
|
471
|
+
|
|
472
|
+
if self.unique_name:
|
|
473
|
+
self._schedule_write()
|
|
474
|
+
|
|
475
|
+
def get_proxy_object(
|
|
476
|
+
self, bus_name: str, path: str, introspection: intr.Node
|
|
477
|
+
) -> ProxyObject:
|
|
478
|
+
return super().get_proxy_object(bus_name, path, introspection)
|
|
479
|
+
|
|
480
|
+
def _schedule_write(self):
|
|
481
|
+
if self.writable_source is None or self.writable_source.is_destroyed():
|
|
482
|
+
self.writable_source = _MessageWritableSource(self)
|
|
483
|
+
self.writable_source.attach(self._main_context)
|
|
484
|
+
self.writable_source.add_unix_fd(self._fd, GLib.IO_OUT)
|
|
485
|
+
|
|
486
|
+
def _authenticate(self, authenticate_notify):
|
|
487
|
+
self._stream.write(b"\0")
|
|
488
|
+
first_line = self._auth._authentication_start()
|
|
489
|
+
if first_line is not None:
|
|
490
|
+
if type(first_line) is not str:
|
|
491
|
+
raise AuthError("authenticator gave response not type str")
|
|
492
|
+
self._stream.write(f"{first_line}\r\n".encode())
|
|
493
|
+
self._stream.flush()
|
|
494
|
+
|
|
495
|
+
def line_notify(line):
|
|
496
|
+
try:
|
|
497
|
+
resp = self._auth._receive_line(line)
|
|
498
|
+
self._stream.write(Authenticator._format_line(resp))
|
|
499
|
+
self._stream.flush()
|
|
500
|
+
if resp == "BEGIN":
|
|
501
|
+
self._readline_source = None
|
|
502
|
+
authenticate_notify(None)
|
|
503
|
+
return True
|
|
504
|
+
except Exception as e:
|
|
505
|
+
authenticate_notify(e)
|
|
506
|
+
return True
|
|
507
|
+
|
|
508
|
+
readline_source = _AuthLineSource(self._stream)
|
|
509
|
+
readline_source.set_callback(line_notify)
|
|
510
|
+
readline_source.add_unix_fd(self._fd, GLib.IO_IN)
|
|
511
|
+
readline_source.attach(self._main_context)
|
|
512
|
+
# make sure it doesnt get cleaned up
|
|
513
|
+
self._readline_source = readline_source
|