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.
Files changed (51) hide show
  1. dbus_fast/__init__.py +82 -0
  2. dbus_fast/__version__.py +10 -0
  3. dbus_fast/_private/__init__.py +1 -0
  4. dbus_fast/_private/_cython_compat.py +14 -0
  5. dbus_fast/_private/address.cpython-310-darwin.so +0 -0
  6. dbus_fast/_private/address.pxd +15 -0
  7. dbus_fast/_private/address.py +119 -0
  8. dbus_fast/_private/constants.py +20 -0
  9. dbus_fast/_private/marshaller.cpython-310-darwin.so +0 -0
  10. dbus_fast/_private/marshaller.pxd +110 -0
  11. dbus_fast/_private/marshaller.py +231 -0
  12. dbus_fast/_private/unmarshaller.cpython-310-darwin.so +0 -0
  13. dbus_fast/_private/unmarshaller.pxd +261 -0
  14. dbus_fast/_private/unmarshaller.py +904 -0
  15. dbus_fast/_private/util.py +177 -0
  16. dbus_fast/aio/__init__.py +5 -0
  17. dbus_fast/aio/message_bus.py +578 -0
  18. dbus_fast/aio/message_reader.cpython-310-darwin.so +0 -0
  19. dbus_fast/aio/message_reader.pxd +13 -0
  20. dbus_fast/aio/message_reader.py +51 -0
  21. dbus_fast/aio/proxy_object.py +208 -0
  22. dbus_fast/auth.py +125 -0
  23. dbus_fast/constants.py +152 -0
  24. dbus_fast/errors.py +81 -0
  25. dbus_fast/glib/__init__.py +3 -0
  26. dbus_fast/glib/message_bus.py +513 -0
  27. dbus_fast/glib/proxy_object.py +318 -0
  28. dbus_fast/introspection.py +686 -0
  29. dbus_fast/message.cpython-310-darwin.so +0 -0
  30. dbus_fast/message.pxd +76 -0
  31. dbus_fast/message.py +389 -0
  32. dbus_fast/message_bus.cpython-310-darwin.so +0 -0
  33. dbus_fast/message_bus.pxd +75 -0
  34. dbus_fast/message_bus.py +1332 -0
  35. dbus_fast/proxy_object.py +357 -0
  36. dbus_fast/py.typed +0 -0
  37. dbus_fast/send_reply.py +61 -0
  38. dbus_fast/service.cpython-310-darwin.so +0 -0
  39. dbus_fast/service.pxd +50 -0
  40. dbus_fast/service.py +727 -0
  41. dbus_fast/signature.cpython-310-darwin.so +0 -0
  42. dbus_fast/signature.pxd +31 -0
  43. dbus_fast/signature.py +484 -0
  44. dbus_fast/unpack.cpython-310-darwin.so +0 -0
  45. dbus_fast/unpack.pxd +13 -0
  46. dbus_fast/unpack.py +28 -0
  47. dbus_fast/validators.py +199 -0
  48. dbus_fast-3.1.2.dist-info/METADATA +262 -0
  49. dbus_fast-3.1.2.dist-info/RECORD +51 -0
  50. dbus_fast-3.1.2.dist-info/WHEEL +6 -0
  51. dbus_fast-3.1.2.dist-info/licenses/LICENSE +22 -0
@@ -0,0 +1,208 @@
1
+ from __future__ import annotations
2
+
3
+ import xml.etree.ElementTree as ET
4
+ from typing import TYPE_CHECKING, Any
5
+
6
+ from .. import introspection as intr
7
+ from .._private.util import replace_fds_with_idx, replace_idx_with_fds
8
+ from ..constants import ErrorType, MessageFlag
9
+ from ..errors import DBusError
10
+ from ..message import Message
11
+ from ..message_bus import BaseMessageBus
12
+ from ..proxy_object import BaseProxyInterface, BaseProxyObject
13
+ from ..signature import Variant
14
+ from ..unpack import unpack_variants as unpack
15
+
16
+ if TYPE_CHECKING:
17
+ from .message_bus import MessageBus as AioMessageBus
18
+
19
+ NO_REPLY_EXPECTED_VALUE = MessageFlag.NO_REPLY_EXPECTED.value
20
+
21
+
22
+ class ProxyInterface(BaseProxyInterface):
23
+ """A class representing a proxy to an interface exported on the bus by
24
+ another client for the asyncio :class:`MessageBus
25
+ <dbus_fast.aio.MessageBus>` implementation.
26
+
27
+ This class is not meant to be constructed directly by the user. Use
28
+ :func:`ProxyObject.get_interface()
29
+ <dbus_fast.aio.ProxyObject.get_interface>` on a asyncio proxy object to get
30
+ a proxy interface.
31
+
32
+ This class exposes methods to call DBus methods, listen to signals, and get
33
+ and set properties on the interface that are created dynamically based on
34
+ the introspection data passed to the proxy object that made this proxy
35
+ interface.
36
+
37
+ A *method call* takes this form:
38
+
39
+ .. code-block:: python3
40
+
41
+ result = await interface.call_[METHOD](*args)
42
+
43
+ Where ``METHOD`` is the name of the method converted to snake case.
44
+
45
+ DBus methods are exposed as coroutines that take arguments that correpond
46
+ to the *in args* of the interface method definition and return a ``result``
47
+ that corresponds to the *out arg*. If the method has more than one out arg,
48
+ they are returned within a :class:`list`.
49
+
50
+ To *listen to a signal* use this form:
51
+
52
+ .. code-block:: python3
53
+
54
+ interface.on_[SIGNAL](callback)
55
+
56
+ To *stop listening to a signal* use this form:
57
+
58
+ .. code-block:: python3
59
+
60
+ interface.off_[SIGNAL](callback)
61
+
62
+ Where ``SIGNAL`` is the name of the signal converted to snake case.
63
+
64
+ DBus signals are exposed with an event-callback interface. The provided
65
+ ``callback`` will be called when the signal is emitted with arguments that
66
+ correspond to the *out args* of the interface signal definition.
67
+
68
+ To *get or set a property* use this form:
69
+
70
+ .. code-block:: python3
71
+
72
+ value = await interface.get_[PROPERTY]()
73
+ await interface.set_[PROPERTY](value)
74
+
75
+ Where ``PROPERTY`` is the name of the property converted to snake case.
76
+
77
+ DBus property getters and setters are exposed as coroutines. The ``value``
78
+ must correspond to the type of the property in the interface definition.
79
+
80
+ If the service returns an error for a DBus call, a :class:`DBusError
81
+ <dbus_fast.DBusError>` will be raised with information about the error.
82
+ """
83
+
84
+ bus: AioMessageBus
85
+
86
+ def _add_method(self, intr_method: intr.Method) -> None:
87
+ async def method_fn(
88
+ *args, flags=MessageFlag.NONE, unpack_variants: bool = False
89
+ ):
90
+ input_body, unix_fds = replace_fds_with_idx(
91
+ intr_method.in_signature, list(args)
92
+ )
93
+
94
+ request = Message(
95
+ destination=self.bus_name,
96
+ path=self.path,
97
+ interface=self.introspection.name,
98
+ member=intr_method.name,
99
+ signature=intr_method.in_signature,
100
+ body=input_body,
101
+ flags=flags,
102
+ unix_fds=unix_fds,
103
+ )
104
+
105
+ if flags & NO_REPLY_EXPECTED_VALUE:
106
+ await self.bus.send(request)
107
+ return None
108
+
109
+ msg = await self.bus.call(request)
110
+
111
+ BaseProxyInterface._check_method_return(msg, intr_method.out_signature)
112
+
113
+ out_len = len(intr_method.out_args)
114
+
115
+ body = replace_idx_with_fds(msg.signature_tree, msg.body, msg.unix_fds)
116
+
117
+ if not out_len:
118
+ return None
119
+
120
+ if unpack_variants:
121
+ body = unpack(body)
122
+
123
+ if out_len == 1:
124
+ return body[0]
125
+ return body
126
+
127
+ method_name = f"call_{BaseProxyInterface._to_snake_case(intr_method.name)}"
128
+ setattr(self, method_name, method_fn)
129
+
130
+ def _add_property(
131
+ self,
132
+ intr_property: intr.Property,
133
+ ) -> None:
134
+ async def property_getter(
135
+ *, flags=MessageFlag.NONE, unpack_variants: bool = False
136
+ ):
137
+ msg = await self.bus.call(
138
+ Message(
139
+ destination=self.bus_name,
140
+ path=self.path,
141
+ interface="org.freedesktop.DBus.Properties",
142
+ member="Get",
143
+ signature="ss",
144
+ body=[self.introspection.name, intr_property.name],
145
+ )
146
+ )
147
+
148
+ BaseProxyInterface._check_method_return(msg, "v")
149
+ variant = msg.body[0]
150
+ if variant.signature != intr_property.signature:
151
+ raise DBusError(
152
+ ErrorType.CLIENT_ERROR,
153
+ f'property returned unexpected signature "{variant.signature}"',
154
+ msg,
155
+ )
156
+
157
+ body = replace_idx_with_fds("v", msg.body, msg.unix_fds)[0].value
158
+
159
+ if unpack_variants:
160
+ return unpack(body)
161
+ return body
162
+
163
+ async def property_setter(val: Any) -> None:
164
+ variant = Variant(intr_property.signature, val)
165
+
166
+ body, unix_fds = replace_fds_with_idx(
167
+ "ssv", [self.introspection.name, intr_property.name, variant]
168
+ )
169
+
170
+ msg = await self.bus.call(
171
+ Message(
172
+ destination=self.bus_name,
173
+ path=self.path,
174
+ interface="org.freedesktop.DBus.Properties",
175
+ member="Set",
176
+ signature="ssv",
177
+ body=body,
178
+ unix_fds=unix_fds,
179
+ )
180
+ )
181
+
182
+ BaseProxyInterface._check_method_return(msg)
183
+
184
+ snake_case = BaseProxyInterface._to_snake_case(intr_property.name)
185
+ setattr(self, f"get_{snake_case}", property_getter)
186
+ setattr(self, f"set_{snake_case}", property_setter)
187
+
188
+
189
+ class ProxyObject(BaseProxyObject):
190
+ """The proxy object implementation for the GLib :class:`MessageBus <dbus_fast.glib.MessageBus>`.
191
+
192
+ For more information, see the :class:`BaseProxyObject <dbus_fast.proxy_object.BaseProxyObject>`.
193
+ """
194
+
195
+ def __init__(
196
+ self,
197
+ bus_name: str,
198
+ path: str,
199
+ introspection: intr.Node | str | ET.Element,
200
+ bus: BaseMessageBus,
201
+ ) -> None:
202
+ super().__init__(bus_name, path, introspection, bus, ProxyInterface)
203
+
204
+ def get_interface(self, name: str) -> ProxyInterface:
205
+ return super().get_interface(name)
206
+
207
+ def get_children(self) -> list[ProxyObject]:
208
+ return super().get_children()
dbus_fast/auth.py ADDED
@@ -0,0 +1,125 @@
1
+ import enum
2
+ import os
3
+
4
+ from .errors import AuthError
5
+
6
+ UID_NOT_SPECIFIED = -1
7
+
8
+ # The auth interface here is unstable. I would like to eventually open this up
9
+ # for people to define their own custom authentication protocols, but I'm not
10
+ # familiar with what's needed for that exactly. To work with any message bus
11
+ # implementation would require abstracting out all the IO. Async operations
12
+ # might be challenging because different IO backends have different ways of
13
+ # doing that. I might just end up giving the raw socket and leaving it all up
14
+ # to the user, but it would be nice to have a little guidance in the interface
15
+ # since a lot of it is strongly specified. If you have a need for this, contact
16
+ # the project maintainer to help stabilize this interface.
17
+
18
+
19
+ class _AuthResponse(enum.Enum):
20
+ OK = "OK"
21
+ REJECTED = "REJECTED"
22
+ DATA = "DATA"
23
+ ERROR = "ERROR"
24
+ AGREE_UNIX_FD = "AGREE_UNIX_FD"
25
+
26
+ @classmethod
27
+ def parse(cls, line: str) -> tuple["_AuthResponse", list[str]]:
28
+ args = line.split(" ")
29
+ response = cls(args[0])
30
+ return response, args[1:]
31
+
32
+
33
+ # UNSTABLE
34
+ class Authenticator:
35
+ """The base class for authenticators for :class:`MessageBus <dbus_fast.message_bus.BaseMessageBus>` authentication.
36
+
37
+ In the future, the library may allow extending this class for custom authentication protocols.
38
+
39
+ :seealso: https://dbus.freedesktop.org/doc/dbus-specification.html#auth-protocol
40
+ """
41
+
42
+ def _authentication_start(self, negotiate_unix_fd: bool = False) -> str:
43
+ raise NotImplementedError(
44
+ "authentication_start() must be implemented in the inheriting class"
45
+ )
46
+
47
+ def _receive_line(self, line: str) -> str:
48
+ raise NotImplementedError(
49
+ "receive_line() must be implemented in the inheriting class"
50
+ )
51
+
52
+ @staticmethod
53
+ def _format_line(line: str) -> bytes:
54
+ return f"{line}\r\n".encode()
55
+
56
+
57
+ class AuthExternal(Authenticator):
58
+ """An authenticator class for the external auth protocol for use with the
59
+ :class:`MessageBus <dbus_fast.message_bus.BaseMessageBus>`.
60
+
61
+ :param uid: The uid to use when connecting to the message bus. Use UID_NOT_SPECIFIED to use the uid known to the kernel.
62
+ :vartype uid: int
63
+
64
+ :sealso: https://dbus.freedesktop.org/doc/dbus-specification.html#auth-protocol
65
+ """
66
+
67
+ def __init__(self, uid: int | None = None) -> None:
68
+ self.negotiate_unix_fd: bool = False
69
+ self.negotiating_fds: bool = False
70
+ self.uid: int | None = uid
71
+
72
+ def _authentication_start(self, negotiate_unix_fd: bool = False) -> str:
73
+ self.negotiate_unix_fd = negotiate_unix_fd
74
+ uid = self.uid
75
+ if uid == UID_NOT_SPECIFIED:
76
+ return "AUTH EXTERNAL"
77
+ if uid is None:
78
+ uid = os.getuid()
79
+ hex_uid = str(uid).encode().hex()
80
+ return f"AUTH EXTERNAL {hex_uid}"
81
+
82
+ def _receive_line(self, line: str) -> str:
83
+ response, args = _AuthResponse.parse(line)
84
+
85
+ if response is _AuthResponse.OK:
86
+ if self.negotiate_unix_fd:
87
+ self.negotiating_fds = True
88
+ return "NEGOTIATE_UNIX_FD"
89
+ return "BEGIN"
90
+
91
+ if response is _AuthResponse.AGREE_UNIX_FD:
92
+ return "BEGIN"
93
+
94
+ if response is _AuthResponse.DATA and self.uid == UID_NOT_SPECIFIED:
95
+ return "DATA"
96
+
97
+ raise AuthError(f"authentication failed: {response.value}: {args}")
98
+
99
+
100
+ class AuthAnonymous(Authenticator):
101
+ """An authenticator class for the anonymous auth protocol for use with the
102
+ :class:`MessageBus <dbus_fast.message_bus.BaseMessageBus>`.
103
+
104
+ :sealso: https://dbus.freedesktop.org/doc/dbus-specification.html#auth-protocol
105
+ """
106
+
107
+ def _authentication_start(self, negotiate_unix_fd: bool = False) -> str:
108
+ if negotiate_unix_fd:
109
+ raise AuthError(
110
+ "anonymous authentication does not support negotiating unix fds right now"
111
+ )
112
+
113
+ return "AUTH ANONYMOUS"
114
+
115
+ def _receive_line(self, line: str) -> str:
116
+ response, args = _AuthResponse.parse(line)
117
+
118
+ if response != _AuthResponse.OK:
119
+ raise AuthError(f"authentication failed: {response.value}: {args}")
120
+
121
+ return "BEGIN"
122
+
123
+
124
+ # The following line provides backwards compatibility, remove at some point? --jrd
125
+ AuthAnnonymous = AuthAnonymous
dbus_fast/constants.py ADDED
@@ -0,0 +1,152 @@
1
+ from enum import Enum, IntFlag
2
+ from functools import cached_property
3
+
4
+
5
+ class BusType(Enum):
6
+ """An enum that indicates a type of bus. On most systems, there are
7
+ normally two different kinds of buses running.
8
+ """
9
+
10
+ SESSION = 1 #: A bus for the current graphical user session.
11
+ SYSTEM = 2 #: A persistent bus for the whole machine.
12
+
13
+
14
+ class MessageType(Enum):
15
+ """An enum that indicates a type of message."""
16
+
17
+ METHOD_CALL = 1 #: An outgoing method call.
18
+ METHOD_RETURN = 2 #: A return to a previously sent method call
19
+ ERROR = 3 #: A return to a method call that has failed
20
+ SIGNAL = 4 #: A broadcast signal to subscribed connections
21
+
22
+ @cached_property
23
+ def value(self) -> int:
24
+ """Return the value."""
25
+ return self._value_
26
+
27
+
28
+ MESSAGE_TYPE_MAP = {field.value: field for field in MessageType}
29
+
30
+
31
+ class MessageFlag(IntFlag):
32
+ """Flags that affect the behavior of sent and received messages"""
33
+
34
+ NONE = 0
35
+ NO_REPLY_EXPECTED = 1 #: The method call does not expect a method return.
36
+ NO_AUTOSTART = 2
37
+ ALLOW_INTERACTIVE_AUTHORIZATION = 4
38
+
39
+ @cached_property
40
+ def value(self) -> int:
41
+ """Return the value."""
42
+ return self._value_
43
+
44
+
45
+ # This is written out because of https://github.com/python/cpython/issues/98976
46
+ MESSAGE_FLAG_MAP = {
47
+ 0: MessageFlag.NONE,
48
+ 1: MessageFlag.NO_REPLY_EXPECTED,
49
+ 2: MessageFlag.NO_AUTOSTART,
50
+ 4: MessageFlag.ALLOW_INTERACTIVE_AUTHORIZATION,
51
+ }
52
+
53
+
54
+ class NameFlag(IntFlag):
55
+ """A flag that affects the behavior of a name request."""
56
+
57
+ NONE = 0
58
+ ALLOW_REPLACEMENT = 1 #: If another client requests this name, let them have it.
59
+ REPLACE_EXISTING = 2 #: If another client owns this name, try to take it.
60
+ DO_NOT_QUEUE = 4 #: Name requests normally queue and wait for the owner to release the name. Do not enter this queue.
61
+
62
+
63
+ class RequestNameReply(Enum):
64
+ """An enum that describes the result of a name request."""
65
+
66
+ PRIMARY_OWNER = 1 #: The bus owns the name.
67
+ IN_QUEUE = 2 #: The bus is in a queue and may receive the name after it is relased by the primary owner.
68
+ EXISTS = 3 #: The name has an owner and NameFlag.DO_NOT_QUEUE was given.
69
+ ALREADY_OWNER = 4 #: The bus already owns the name.
70
+
71
+
72
+ class ReleaseNameReply(Enum):
73
+ """An enum that describes the result of a name release request"""
74
+
75
+ RELEASED = 1
76
+ NON_EXISTENT = 2
77
+ NOT_OWNER = 3
78
+
79
+
80
+ class PropertyAccess(Enum):
81
+ """An enum that describes whether a DBus property can be gotten or set with
82
+ the ``org.freedesktop.DBus.Properties`` interface.
83
+ """
84
+
85
+ READ = "read" #: The property is readonly.
86
+ WRITE = "write" #: The property is writeonly.
87
+ READWRITE = "readwrite" #: The property can be read or written to.
88
+
89
+ def readable(self) -> bool:
90
+ """Get whether the property can be read."""
91
+ return self == PropertyAccess.READ or self == PropertyAccess.READWRITE
92
+
93
+ def writable(self) -> bool:
94
+ """Get whether the property can be written to."""
95
+ return self == PropertyAccess.WRITE or self == PropertyAccess.READWRITE
96
+
97
+
98
+ class ArgDirection(Enum):
99
+ """For an introspected argument, indicates whether it is an input parameter or a return value."""
100
+
101
+ IN = "in"
102
+ OUT = "out"
103
+
104
+
105
+ class ErrorType(str, Enum):
106
+ """An enum for the type of an error for a message reply.
107
+
108
+ :seealso: http://man7.org/linux/man-pages/man3/sd-bus-errors.3.html
109
+ """
110
+
111
+ SERVICE_ERROR = "com.dubstepdish.dbus.next.ServiceError" #: A custom error to indicate an exported service threw an exception.
112
+ INTERNAL_ERROR = "com.dubstepdish.dbus.next.InternalError" #: A custom error to indicate something went wrong with the library.
113
+ CLIENT_ERROR = "com.dubstepdish.dbus.next.ClientError" #: A custom error to indicate something went wrong with the client.
114
+
115
+ FAILED = "org.freedesktop.DBus.Error.Failed"
116
+ NO_MEMORY = "org.freedesktop.DBus.Error.NoMemory"
117
+ SERVICE_UNKNOWN = "org.freedesktop.DBus.Error.ServiceUnknown"
118
+ NAME_HAS_NO_OWNER = "org.freedesktop.DBus.Error.NameHasNoOwner"
119
+ NO_REPLY = "org.freedesktop.DBus.Error.NoReply"
120
+ IO_ERROR = "org.freedesktop.DBus.Error.IOError"
121
+ BAD_ADDRESS = "org.freedesktop.DBus.Error.BadAddress"
122
+ NOT_SUPPORTED = "org.freedesktop.DBus.Error.NotSupported"
123
+ LIMITS_EXCEEDED = "org.freedesktop.DBus.Error.LimitsExceeded"
124
+ ACCESS_DENIED = "org.freedesktop.DBus.Error.AccessDenied"
125
+ AUTH_FAILED = "org.freedesktop.DBus.Error.AuthFailed"
126
+ NO_SERVER = "org.freedesktop.DBus.Error.NoServer"
127
+ TIMEOUT = "org.freedesktop.DBus.Error.Timeout"
128
+ NO_NETWORK = "org.freedesktop.DBus.Error.NoNetwork"
129
+ ADDRESS_IN_USE = "org.freedesktop.DBus.Error.AddressInUse"
130
+ DISCONNECTED = "org.freedesktop.DBus.Error.Disconnected"
131
+ INVALID_ARGS = "org.freedesktop.DBus.Error.InvalidArgs"
132
+ FILE_NOT_FOUND = "org.freedesktop.DBus.Error.FileNotFound"
133
+ FILE_EXISTS = "org.freedesktop.DBus.Error.FileExists"
134
+ UNKNOWN_METHOD = "org.freedesktop.DBus.Error.UnknownMethod"
135
+ UNKNOWN_OBJECT = "org.freedesktop.DBus.Error.UnknownObject"
136
+ UNKNOWN_INTERFACE = "org.freedesktop.DBus.Error.UnknownInterface"
137
+ UNKNOWN_PROPERTY = "org.freedesktop.DBus.Error.UnknownProperty"
138
+ PROPERTY_READ_ONLY = "org.freedesktop.DBus.Error.PropertyReadOnly"
139
+ UNIX_PROCESS_ID_UNKNOWN = "org.freedesktop.DBus.Error.UnixProcessIdUnknown"
140
+ INVALID_SIGNATURE = "org.freedesktop.DBus.Error.InvalidSignature"
141
+ INCONSISTENT_MESSAGE = "org.freedesktop.DBus.Error.InconsistentMessage"
142
+ TIMED_OUT = "org.freedesktop.DBus.Error.TimedOut"
143
+ MATCH_RULE_NOT_FOUND = "org.freedesktop.DBus.Error.MatchRuleNotFound"
144
+ MATCH_RULE_INVALID = "org.freedesktop.DBus.Error.MatchRuleInvalid"
145
+ INTERACTIVE_AUTHORIZATION_REQUIRED = (
146
+ "org.freedesktop.DBus.Error.InteractiveAuthorizationRequired"
147
+ )
148
+ INVALID_FILE_CONTENT = "org.freedesktop.DBus.Error.InvalidFileContent"
149
+ SELINUX_SECURITY_CONTEXT_UNKNOWN = (
150
+ "org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown"
151
+ )
152
+ OBJECT_PATH_IN_USE = "org.freedesktop.DBus.Error.ObjectPathInUse"
dbus_fast/errors.py ADDED
@@ -0,0 +1,81 @@
1
+ class SignatureBodyMismatchError(ValueError):
2
+ pass
3
+
4
+
5
+ class InvalidSignatureError(ValueError):
6
+ pass
7
+
8
+
9
+ class InvalidAddressError(ValueError):
10
+ pass
11
+
12
+
13
+ class AuthError(Exception):
14
+ pass
15
+
16
+
17
+ class InvalidMessageError(ValueError):
18
+ pass
19
+
20
+
21
+ class InvalidIntrospectionError(ValueError):
22
+ pass
23
+
24
+
25
+ class InterfaceNotFoundError(Exception):
26
+ pass
27
+
28
+
29
+ class SignalDisabledError(Exception):
30
+ pass
31
+
32
+
33
+ class InvalidBusNameError(TypeError):
34
+ def __init__(self, name: str) -> None:
35
+ super().__init__(f"invalid bus name: {name}")
36
+
37
+
38
+ class InvalidObjectPathError(TypeError):
39
+ def __init__(self, path: str) -> None:
40
+ super().__init__(f"invalid object path: {path}")
41
+
42
+
43
+ class InvalidInterfaceNameError(TypeError):
44
+ def __init__(self, name: str) -> None:
45
+ super().__init__(f"invalid interface name: {name}")
46
+
47
+
48
+ class InvalidMemberNameError(TypeError):
49
+ def __init__(self, member: str) -> None:
50
+ super().__init__(f"invalid member name: {member}")
51
+
52
+
53
+ from .constants import ErrorType, MessageType # noqa: E402
54
+ from .message import Message # noqa: E402
55
+ from .validators import assert_interface_name_valid # noqa: E402
56
+
57
+
58
+ class DBusError(Exception):
59
+ def __init__(
60
+ self, type_: ErrorType | str, text: str, reply: Message | None = None
61
+ ) -> None:
62
+ super().__init__(text)
63
+
64
+ if type(type_) is ErrorType:
65
+ type_ = type_.value
66
+
67
+ assert_interface_name_valid(type_) # type: ignore[arg-type]
68
+ if reply is not None and type(reply) is not Message:
69
+ raise TypeError("reply must be of type Message")
70
+
71
+ self.type = type_
72
+ self.text = text
73
+ self.reply = reply
74
+
75
+ @staticmethod
76
+ def _from_message(msg: Message) -> "DBusError":
77
+ assert msg.message_type == MessageType.ERROR
78
+ return DBusError(msg.error_name or "unknown", msg.body[0], reply=msg)
79
+
80
+ def _as_message(self, msg: Message) -> Message:
81
+ return Message.new_error(msg, self.type, self.text)
@@ -0,0 +1,3 @@
1
+ from .message_bus import MessageBus as MessageBus
2
+ from .proxy_object import ProxyInterface as ProxyInterface
3
+ from .proxy_object import ProxyObject as ProxyObject