chore: drop Python 3.8 support as it has reached EOL (#338)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
3
.github/workflows/ci.yml
vendored
3
.github/workflows/ci.yml
vendored
@@ -36,7 +36,6 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
python-version:
|
python-version:
|
||||||
- "3.8"
|
|
||||||
- "3.9"
|
- "3.9"
|
||||||
- "3.10"
|
- "3.10"
|
||||||
- "3.11"
|
- "3.11"
|
||||||
@@ -145,7 +144,7 @@ jobs:
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Install cibuildwheel
|
- name: Install cibuildwheel
|
||||||
run: python -m pip install cibuildwheel==2.20.0
|
run: python -m pip install cibuildwheel==2.22.0
|
||||||
|
|
||||||
- name: Build wheels
|
- name: Build wheels
|
||||||
run: python -m cibuildwheel --output-dir wheelhouse
|
run: python -m cibuildwheel --output-dir wheelhouse
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ repos:
|
|||||||
rev: v3.19.1
|
rev: v3.19.1
|
||||||
hooks:
|
hooks:
|
||||||
- id: pyupgrade
|
- id: pyupgrade
|
||||||
args: [--py37-plus]
|
args: [--py39-plus]
|
||||||
- repo: https://github.com/PyCQA/isort
|
- repo: https://github.com/PyCQA/isort
|
||||||
rev: 5.13.2
|
rev: 5.13.2
|
||||||
hooks:
|
hooks:
|
||||||
|
|||||||
746
poetry.lock
generated
746
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -34,7 +34,7 @@ script = "build_ext.py"
|
|||||||
"Changelog" = "https://github.com/bluetooth-devices/dbus-fast/blob/main/CHANGELOG.md"
|
"Changelog" = "https://github.com/bluetooth-devices/dbus-fast/blob/main/CHANGELOG.md"
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = "^3.8"
|
python = "^3.9"
|
||||||
|
|
||||||
# duplicated in docs/requirements.txt for readthedocs compatibility
|
# duplicated in docs/requirements.txt for readthedocs compatibility
|
||||||
[tool.poetry.group.docs.dependencies]
|
[tool.poetry.group.docs.dependencies]
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ invalid_address_chars_re = re.compile(r"[^-0-9A-Za-z_/.%]")
|
|||||||
str_ = str
|
str_ = str
|
||||||
|
|
||||||
|
|
||||||
def parse_address(address_str: str_) -> List[Tuple[str, Dict[str, str]]]:
|
def parse_address(address_str: str_) -> list[tuple[str, dict[str, str]]]:
|
||||||
"""Parse a dbus address string into a list of addresses."""
|
"""Parse a dbus address string into a list of addresses."""
|
||||||
addresses: List[Tuple[str, Dict[str, str]]] = []
|
addresses: list[tuple[str, dict[str, str]]] = []
|
||||||
|
|
||||||
for address in address_str.split(";"):
|
for address in address_str.split(";"):
|
||||||
if not address:
|
if not address:
|
||||||
@@ -22,7 +22,7 @@ def parse_address(address_str: str_) -> List[Tuple[str, Dict[str, str]]]:
|
|||||||
raise InvalidAddressError("address did not contain a transport")
|
raise InvalidAddressError("address did not contain a transport")
|
||||||
|
|
||||||
transport, opt_string = address.split(":", 1)
|
transport, opt_string = address.split(":", 1)
|
||||||
options: Dict[str, str] = {}
|
options: dict[str, str] = {}
|
||||||
|
|
||||||
for kv in opt_string.split(","):
|
for kv in opt_string.split(","):
|
||||||
if not kv:
|
if not kv:
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class Marshaller:
|
|||||||
|
|
||||||
__slots__ = ("signature_tree", "_buf", "body")
|
__slots__ = ("signature_tree", "_buf", "body")
|
||||||
|
|
||||||
def __init__(self, signature: str, body: List[Any]) -> None:
|
def __init__(self, signature: str, body: list[Any]) -> None:
|
||||||
"""Marshaller constructor."""
|
"""Marshaller constructor."""
|
||||||
self.signature_tree = get_signature_tree(signature)
|
self.signature_tree = get_signature_tree(signature)
|
||||||
self._buf = bytearray()
|
self._buf = bytearray()
|
||||||
@@ -89,12 +89,12 @@ class Marshaller:
|
|||||||
return written
|
return written
|
||||||
|
|
||||||
def write_array(
|
def write_array(
|
||||||
self, array: Union[List[Any], Dict[Any, Any]], type_: SignatureType
|
self, array: Union[list[Any], dict[Any, Any]], type_: SignatureType
|
||||||
) -> int:
|
) -> int:
|
||||||
return self._write_array(array, type_)
|
return self._write_array(array, type_)
|
||||||
|
|
||||||
def _write_array(
|
def _write_array(
|
||||||
self, array: Union[List[Any], Dict[Any, Any]], type_: SignatureType
|
self, array: Union[list[Any], dict[Any, Any]], type_: SignatureType
|
||||||
) -> int:
|
) -> int:
|
||||||
# TODO max array size is 64MiB (67108864 bytes)
|
# TODO max array size is 64MiB (67108864 bytes)
|
||||||
written = self._align(4)
|
written = self._align(4)
|
||||||
@@ -137,19 +137,19 @@ class Marshaller:
|
|||||||
return written + array_len
|
return written + array_len
|
||||||
|
|
||||||
def write_struct(
|
def write_struct(
|
||||||
self, array: Union[Tuple[Any], List[Any]], type_: SignatureType
|
self, array: Union[tuple[Any], list[Any]], type_: SignatureType
|
||||||
) -> int:
|
) -> int:
|
||||||
return self._write_struct(array, type_)
|
return self._write_struct(array, type_)
|
||||||
|
|
||||||
def _write_struct(
|
def _write_struct(
|
||||||
self, array: Union[Tuple[Any], List[Any]], type_: SignatureType
|
self, array: Union[tuple[Any], list[Any]], type_: SignatureType
|
||||||
) -> int:
|
) -> int:
|
||||||
written = self._align(8)
|
written = self._align(8)
|
||||||
for i, value in enumerate(array):
|
for i, value in enumerate(array):
|
||||||
written += self._write_single(type_.children[i], value)
|
written += self._write_single(type_.children[i], value)
|
||||||
return written
|
return written
|
||||||
|
|
||||||
def write_dict_entry(self, dict_entry: List[Any], type_: SignatureType) -> int:
|
def write_dict_entry(self, dict_entry: list[Any], type_: SignatureType) -> int:
|
||||||
written = self._align(8)
|
written = self._align(8)
|
||||||
written += self._write_single(type_.children[0], dict_entry[0])
|
written += self._write_single(type_.children[0], dict_entry[0])
|
||||||
written += self._write_single(type_.children[1], dict_entry[1])
|
written += self._write_single(type_.children[1], dict_entry[1])
|
||||||
@@ -201,9 +201,9 @@ class Marshaller:
|
|||||||
self._write_single(type_, body[i])
|
self._write_single(type_, body[i])
|
||||||
return self._buf
|
return self._buf
|
||||||
|
|
||||||
_writers: Dict[
|
_writers: dict[
|
||||||
str,
|
str,
|
||||||
Tuple[
|
tuple[
|
||||||
Optional[Callable[[Any, Any, SignatureType], int]],
|
Optional[Callable[[Any, Any, SignatureType], int]],
|
||||||
Optional[Callable[[Any], bytes]],
|
Optional[Callable[[Any], bytes]],
|
||||||
int,
|
int,
|
||||||
|
|||||||
@@ -3,8 +3,9 @@ import errno
|
|||||||
import io
|
import io
|
||||||
import socket
|
import socket
|
||||||
import sys
|
import sys
|
||||||
|
from collections.abc import Iterable
|
||||||
from struct import Struct
|
from struct import Struct
|
||||||
from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, Union
|
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
|
||||||
|
|
||||||
from ..constants import MESSAGE_FLAG_MAP, MESSAGE_TYPE_MAP, MessageFlag
|
from ..constants import MESSAGE_FLAG_MAP, MESSAGE_TYPE_MAP, MessageFlag
|
||||||
from ..errors import InvalidMessageError
|
from ..errors import InvalidMessageError
|
||||||
@@ -157,9 +158,9 @@ def unpack_parser_factory(unpack_from: Callable, size: int) -> READER_TYPE:
|
|||||||
|
|
||||||
def build_simple_parsers(
|
def build_simple_parsers(
|
||||||
endian: int,
|
endian: int,
|
||||||
) -> Dict[str, Callable[["Unmarshaller", SignatureType], Any]]:
|
) -> dict[str, Callable[["Unmarshaller", SignatureType], Any]]:
|
||||||
"""Build a dict of parsers for simple types."""
|
"""Build a dict of parsers for simple types."""
|
||||||
parsers: Dict[str, READER_TYPE] = {}
|
parsers: dict[str, READER_TYPE] = {}
|
||||||
for dbus_type, ctype_size in DBUS_TO_CTYPE.items():
|
for dbus_type, ctype_size in DBUS_TO_CTYPE.items():
|
||||||
ctype, size = ctype_size
|
ctype, size = ctype_size
|
||||||
size = ctype_size[1]
|
size = ctype_size[1]
|
||||||
@@ -231,12 +232,12 @@ class Unmarshaller:
|
|||||||
sock: Optional[socket.socket] = None,
|
sock: Optional[socket.socket] = None,
|
||||||
negotiate_unix_fd: bool = True,
|
negotiate_unix_fd: bool = True,
|
||||||
) -> None:
|
) -> None:
|
||||||
self._unix_fds: List[int] = []
|
self._unix_fds: list[int] = []
|
||||||
self._buf = bytearray() # Actual buffer
|
self._buf = bytearray() # Actual buffer
|
||||||
self._stream = stream
|
self._stream = stream
|
||||||
self._sock = sock
|
self._sock = sock
|
||||||
self._message: Optional[Message] = None
|
self._message: Optional[Message] = None
|
||||||
self._readers: Dict[str, READER_TYPE] = {}
|
self._readers: dict[str, READER_TYPE] = {}
|
||||||
self._pos = 0
|
self._pos = 0
|
||||||
self._body_len = 0
|
self._body_len = 0
|
||||||
self._serial = 0
|
self._serial = 0
|
||||||
@@ -494,14 +495,14 @@ class Unmarshaller:
|
|||||||
False,
|
False,
|
||||||
)
|
)
|
||||||
|
|
||||||
def read_struct(self, type_: _SignatureType) -> List[Any]:
|
def read_struct(self, type_: _SignatureType) -> list[Any]:
|
||||||
self._pos += -self._pos & 7 # align 8
|
self._pos += -self._pos & 7 # align 8
|
||||||
readers = self._readers
|
readers = self._readers
|
||||||
return [
|
return [
|
||||||
readers[child_type.token](self, child_type) for child_type in type_.children
|
readers[child_type.token](self, child_type) for child_type in type_.children
|
||||||
]
|
]
|
||||||
|
|
||||||
def read_dict_entry(self, type_: _SignatureType) -> Tuple[Any, Any]:
|
def read_dict_entry(self, type_: _SignatureType) -> tuple[Any, Any]:
|
||||||
self._pos += -self._pos & 7 # align 8
|
self._pos += -self._pos & 7 # align 8
|
||||||
return self._readers[type_.children[0].token](
|
return self._readers[type_.children[0].token](
|
||||||
self, type_.children[0]
|
self, type_.children[0]
|
||||||
@@ -537,7 +538,7 @@ class Unmarshaller:
|
|||||||
return self._buf[self._pos - array_length : self._pos]
|
return self._buf[self._pos - array_length : self._pos]
|
||||||
|
|
||||||
if token_as_int == TOKEN_LEFT_CURLY_AS_INT:
|
if token_as_int == TOKEN_LEFT_CURLY_AS_INT:
|
||||||
result_dict: Dict[Any, Any] = {}
|
result_dict: dict[Any, Any] = {}
|
||||||
beginning_pos = self._pos
|
beginning_pos = self._pos
|
||||||
children = child_type.children
|
children = child_type.children
|
||||||
child_0 = children[0]
|
child_0 = children[0]
|
||||||
@@ -595,7 +596,7 @@ class Unmarshaller:
|
|||||||
result_list.append(reader(self, child_type))
|
result_list.append(reader(self, child_type))
|
||||||
return result_list
|
return result_list
|
||||||
|
|
||||||
def _header_fields(self, header_length: _int) -> Dict[str, Any]:
|
def _header_fields(self, header_length: _int) -> dict[str, Any]:
|
||||||
"""Header fields are always a(yv)."""
|
"""Header fields are always a(yv)."""
|
||||||
beginning_pos = self._pos
|
beginning_pos = self._pos
|
||||||
headers = {}
|
headers = {}
|
||||||
@@ -696,7 +697,7 @@ class Unmarshaller:
|
|||||||
signature = header_fields.pop("signature", "")
|
signature = header_fields.pop("signature", "")
|
||||||
if not self._body_len:
|
if not self._body_len:
|
||||||
tree = SIGNATURE_TREE_EMPTY
|
tree = SIGNATURE_TREE_EMPTY
|
||||||
body: List[Any] = []
|
body: list[Any] = []
|
||||||
else:
|
else:
|
||||||
token_as_int = ord(signature[0])
|
token_as_int = ord(signature[0])
|
||||||
if len(signature) == 1:
|
if len(signature) == 1:
|
||||||
@@ -778,7 +779,7 @@ class Unmarshaller:
|
|||||||
return None
|
return None
|
||||||
return self._message
|
return self._message
|
||||||
|
|
||||||
_complex_parsers_unpack: Dict[
|
_complex_parsers_unpack: dict[
|
||||||
str, Callable[["Unmarshaller", SignatureType], Any]
|
str, Callable[["Unmarshaller", SignatureType], Any]
|
||||||
] = {
|
] = {
|
||||||
"b": read_boolean,
|
"b": read_boolean,
|
||||||
@@ -795,11 +796,11 @@ class Unmarshaller:
|
|||||||
UINT16_DBUS_TYPE: read_uint16_unpack,
|
UINT16_DBUS_TYPE: read_uint16_unpack,
|
||||||
}
|
}
|
||||||
|
|
||||||
_ctype_by_endian: Dict[int, Dict[str, READER_TYPE]] = {
|
_ctype_by_endian: dict[int, dict[str, READER_TYPE]] = {
|
||||||
endian: build_simple_parsers(endian) for endian in (LITTLE_ENDIAN, BIG_ENDIAN)
|
endian: build_simple_parsers(endian) for endian in (LITTLE_ENDIAN, BIG_ENDIAN)
|
||||||
}
|
}
|
||||||
|
|
||||||
_readers_by_type: Dict[int, Dict[str, READER_TYPE]] = {
|
_readers_by_type: dict[int, dict[str, READER_TYPE]] = {
|
||||||
LITTLE_ENDIAN: {
|
LITTLE_ENDIAN: {
|
||||||
**_ctype_by_endian[LITTLE_ENDIAN],
|
**_ctype_by_endian[LITTLE_ENDIAN],
|
||||||
**_complex_parsers_unpack,
|
**_complex_parsers_unpack,
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from ..signature import SignatureTree, Variant, get_signature_tree
|
|||||||
|
|
||||||
|
|
||||||
def signature_contains_type(
|
def signature_contains_type(
|
||||||
signature: Union[str, SignatureTree], body: List[Any], token: str
|
signature: Union[str, SignatureTree], body: list[Any], token: str
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""For a given signature and body, check to see if it contains any members
|
"""For a given signature and body, check to see if it contains any members
|
||||||
with the given token"""
|
with the given token"""
|
||||||
@@ -49,8 +49,8 @@ def signature_contains_type(
|
|||||||
|
|
||||||
|
|
||||||
def replace_fds_with_idx(
|
def replace_fds_with_idx(
|
||||||
signature: Union[str, SignatureTree], body: List[Any]
|
signature: Union[str, SignatureTree], body: list[Any]
|
||||||
) -> Tuple[List[Any], List[int]]:
|
) -> tuple[list[Any], list[int]]:
|
||||||
"""Take the high level body format and convert it into the low level body
|
"""Take the high level body format and convert it into the low level body
|
||||||
format. Type 'h' refers directly to the fd in the body. Replace that with
|
format. Type 'h' refers directly to the fd in the body. Replace that with
|
||||||
an index and return the corresponding list of unix fds that can be set on
|
an index and return the corresponding list of unix fds that can be set on
|
||||||
@@ -76,8 +76,8 @@ def replace_fds_with_idx(
|
|||||||
|
|
||||||
|
|
||||||
def replace_idx_with_fds(
|
def replace_idx_with_fds(
|
||||||
signature: Union[str, SignatureTree], body: List[Any], unix_fds: List[int]
|
signature: Union[str, SignatureTree], body: list[Any], unix_fds: list[int]
|
||||||
) -> List[Any]:
|
) -> list[Any]:
|
||||||
"""Take the low level body format and return the high level body format.
|
"""Take the low level body format and return the high level body format.
|
||||||
Type 'h' refers to an index in the unix_fds array. Replace those with the
|
Type 'h' refers to an index in the unix_fds array. Replace those with the
|
||||||
actual file descriptor or `None` if one does not exist."""
|
actual file descriptor or `None` if one does not exist."""
|
||||||
@@ -128,7 +128,7 @@ def parse_annotation(annotation: str) -> str:
|
|||||||
return annotation
|
return annotation
|
||||||
|
|
||||||
|
|
||||||
def _replace_fds(body_obj: List[Any], children, replace_fn):
|
def _replace_fds(body_obj: list[Any], children, replace_fn):
|
||||||
"""Replace any type 'h' with the value returned by replace_fn() given the
|
"""Replace any type 'h' with the value returned by replace_fn() given the
|
||||||
value of the fd field. This is used by the high level interfaces which
|
value of the fd field. This is used by the high level interfaces which
|
||||||
allow type 'h' to be the fd directly instead of an index in an external
|
allow type 'h' to be the fd directly instead of an index in an external
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class _MessageWriter:
|
|||||||
def __init__(self, bus: "MessageBus") -> None:
|
def __init__(self, bus: "MessageBus") -> None:
|
||||||
"""A class to handle writing messages to the message bus."""
|
"""A class to handle writing messages to the message bus."""
|
||||||
self.messages: deque[
|
self.messages: deque[
|
||||||
Tuple[bytearray, Optional[List[int]], Optional[asyncio.Future]]
|
tuple[bytearray, Optional[list[int]], Optional[asyncio.Future]]
|
||||||
] = deque()
|
] = deque()
|
||||||
self.negotiate_unix_fd = bus._negotiate_unix_fd
|
self.negotiate_unix_fd = bus._negotiate_unix_fd
|
||||||
self.bus = bus
|
self.bus = bus
|
||||||
@@ -66,7 +66,7 @@ class _MessageWriter:
|
|||||||
self.buf: Optional[memoryview] = None
|
self.buf: Optional[memoryview] = None
|
||||||
self.fd = bus._fd
|
self.fd = bus._fd
|
||||||
self.offset = 0
|
self.offset = 0
|
||||||
self.unix_fds: Optional[List[int]] = None
|
self.unix_fds: Optional[list[int]] = None
|
||||||
self.fut: Optional[asyncio.Future] = None
|
self.fut: Optional[asyncio.Future] = None
|
||||||
|
|
||||||
def write_callback(self, remove_writer: bool = True) -> None:
|
def write_callback(self, remove_writer: bool = True) -> None:
|
||||||
@@ -208,7 +208,7 @@ class MessageBus(BaseMessageBus):
|
|||||||
self._auth = auth
|
self._auth = auth
|
||||||
|
|
||||||
self._disconnect_future = self._loop.create_future()
|
self._disconnect_future = self._loop.create_future()
|
||||||
self._pending_futures: Set[asyncio.Future] = set()
|
self._pending_futures: set[asyncio.Future] = set()
|
||||||
|
|
||||||
async def connect(self) -> "MessageBus":
|
async def connect(self) -> "MessageBus":
|
||||||
"""Connect this message bus to the DBus daemon.
|
"""Connect this message bus to the DBus daemon.
|
||||||
|
|||||||
@@ -201,5 +201,5 @@ class ProxyObject(BaseProxyObject):
|
|||||||
def get_interface(self, name: str) -> ProxyInterface:
|
def get_interface(self, name: str) -> ProxyInterface:
|
||||||
return super().get_interface(name)
|
return super().get_interface(name)
|
||||||
|
|
||||||
def get_children(self) -> List["ProxyObject"]:
|
def get_children(self) -> list["ProxyObject"]:
|
||||||
return super().get_children()
|
return super().get_children()
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class _AuthResponse(enum.Enum):
|
|||||||
AGREE_UNIX_FD = "AGREE_UNIX_FD"
|
AGREE_UNIX_FD = "AGREE_UNIX_FD"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def parse(klass, line: str) -> Tuple["_AuthResponse", List[str]]:
|
def parse(klass, line: str) -> tuple["_AuthResponse", list[str]]:
|
||||||
args = line.split(" ")
|
args = line.split(" ")
|
||||||
response = klass(args[0])
|
response = klass(args[0])
|
||||||
return response, args[1:]
|
return response, args[1:]
|
||||||
|
|||||||
@@ -316,5 +316,5 @@ class ProxyObject(BaseProxyObject):
|
|||||||
def get_interface(self, name: str) -> ProxyInterface:
|
def get_interface(self, name: str) -> ProxyInterface:
|
||||||
return super().get_interface(name)
|
return super().get_interface(name)
|
||||||
|
|
||||||
def get_children(self) -> List["ProxyObject"]:
|
def get_children(self) -> list["ProxyObject"]:
|
||||||
return super().get_children()
|
return super().get_children()
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ class Arg:
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
signature: Union[SignatureType, str],
|
signature: Union[SignatureType, str],
|
||||||
direction: Optional[List[ArgDirection]] = None,
|
direction: Optional[list[ArgDirection]] = None,
|
||||||
name: Optional[str] = None,
|
name: Optional[str] = None,
|
||||||
):
|
):
|
||||||
if name is not None:
|
if name is not None:
|
||||||
@@ -105,7 +105,7 @@ class Signal:
|
|||||||
- :class:`InvalidMemberNameError <dbus_fast.InvalidMemberNameError>` - If the name of the signal is not a valid member name.
|
- :class:`InvalidMemberNameError <dbus_fast.InvalidMemberNameError>` - If the name of the signal is not a valid member name.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, name: Optional[str], args: Optional[List[Arg]] = None):
|
def __init__(self, name: Optional[str], args: Optional[list[Arg]] = None):
|
||||||
if name is not None:
|
if name is not None:
|
||||||
assert_member_name_valid(name)
|
assert_member_name_valid(name)
|
||||||
|
|
||||||
@@ -168,7 +168,7 @@ class Method:
|
|||||||
- :class:`InvalidMemberNameError <dbus_fast.InvalidMemberNameError>` - If the name of this method is not valid.
|
- :class:`InvalidMemberNameError <dbus_fast.InvalidMemberNameError>` - If the name of this method is not valid.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, name: str, in_args: List[Arg] = [], out_args: List[Arg] = []):
|
def __init__(self, name: str, in_args: list[Arg] = [], out_args: list[Arg] = []):
|
||||||
assert_member_name_valid(name)
|
assert_member_name_valid(name)
|
||||||
|
|
||||||
self.name = name
|
self.name = name
|
||||||
@@ -312,9 +312,9 @@ class Interface:
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
name: str,
|
name: str,
|
||||||
methods: Optional[List[Method]] = None,
|
methods: Optional[list[Method]] = None,
|
||||||
signals: Optional[List[Signal]] = None,
|
signals: Optional[list[Signal]] = None,
|
||||||
properties: Optional[List[Property]] = None,
|
properties: Optional[list[Property]] = None,
|
||||||
):
|
):
|
||||||
assert_interface_name_valid(name)
|
assert_interface_name_valid(name)
|
||||||
|
|
||||||
@@ -397,7 +397,7 @@ class Node:
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
name: Optional[str] = None,
|
name: Optional[str] = None,
|
||||||
interfaces: Optional[List[Interface]] = None,
|
interfaces: Optional[list[Interface]] = None,
|
||||||
is_root: bool = True,
|
is_root: bool = True,
|
||||||
):
|
):
|
||||||
if not is_root and not name:
|
if not is_root and not name:
|
||||||
|
|||||||
@@ -109,9 +109,9 @@ class Message:
|
|||||||
error_name: Optional[Union[str, ErrorType]] = None,
|
error_name: Optional[Union[str, ErrorType]] = None,
|
||||||
reply_serial: int = 0,
|
reply_serial: int = 0,
|
||||||
sender: Optional[str] = None,
|
sender: Optional[str] = None,
|
||||||
unix_fds: List[int] = [],
|
unix_fds: list[int] = [],
|
||||||
signature: Optional[Union[SignatureTree, str]] = None,
|
signature: Optional[Union[SignatureTree, str]] = None,
|
||||||
body: List[Any] = [],
|
body: list[Any] = [],
|
||||||
serial: int = 0,
|
serial: int = 0,
|
||||||
validate: bool = True,
|
validate: bool = True,
|
||||||
) -> None:
|
) -> None:
|
||||||
@@ -203,8 +203,8 @@ class Message:
|
|||||||
def new_method_return(
|
def new_method_return(
|
||||||
msg: "Message",
|
msg: "Message",
|
||||||
signature: str = "",
|
signature: str = "",
|
||||||
body: List[Any] = [],
|
body: list[Any] = [],
|
||||||
unix_fds: List[int] = [],
|
unix_fds: list[int] = [],
|
||||||
) -> "Message":
|
) -> "Message":
|
||||||
"""A convenience constructor to create a method return to the given method call message.
|
"""A convenience constructor to create a method return to the given method call message.
|
||||||
|
|
||||||
@@ -238,8 +238,8 @@ class Message:
|
|||||||
interface: str,
|
interface: str,
|
||||||
member: str,
|
member: str,
|
||||||
signature: str = "",
|
signature: str = "",
|
||||||
body: Optional[List[Any]] = None,
|
body: Optional[list[Any]] = None,
|
||||||
unix_fds: Optional[List[int]] = None,
|
unix_fds: Optional[list[int]] = None,
|
||||||
) -> "Message":
|
) -> "Message":
|
||||||
"""A convenience constructor to create a new signal message.
|
"""A convenience constructor to create a new signal message.
|
||||||
|
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ class BaseMessageBus:
|
|||||||
self,
|
self,
|
||||||
bus_address: Optional[str] = None,
|
bus_address: Optional[str] = None,
|
||||||
bus_type: BusType = BusType.SESSION,
|
bus_type: BusType = BusType.SESSION,
|
||||||
ProxyObject: Optional[Type[BaseProxyObject]] = None,
|
ProxyObject: Optional[type[BaseProxyObject]] = None,
|
||||||
negotiate_unix_fd: bool = False,
|
negotiate_unix_fd: bool = False,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.unique_name: Optional[str] = None
|
self.unique_name: Optional[str] = None
|
||||||
@@ -132,20 +132,20 @@ class BaseMessageBus:
|
|||||||
# the main loop.
|
# the main loop.
|
||||||
self._user_disconnect = False
|
self._user_disconnect = False
|
||||||
|
|
||||||
self._method_return_handlers: Dict[
|
self._method_return_handlers: dict[
|
||||||
int, Callable[[Optional[Message], Optional[Exception]], None]
|
int, Callable[[Optional[Message], Optional[Exception]], None]
|
||||||
] = {}
|
] = {}
|
||||||
self._serial = 0
|
self._serial = 0
|
||||||
self._user_message_handlers: List[
|
self._user_message_handlers: list[
|
||||||
Callable[[Message], Union[Message, bool, None]]
|
Callable[[Message], Union[Message, bool, None]]
|
||||||
] = []
|
] = []
|
||||||
# the key is the name and the value is the unique name of the owner.
|
# the key is the name and the value is the unique name of the owner.
|
||||||
# This cache is kept up to date by the NameOwnerChanged signal and is
|
# This cache is kept up to date by the NameOwnerChanged signal and is
|
||||||
# used to route messages to the correct proxy object. (used for the
|
# used to route messages to the correct proxy object. (used for the
|
||||||
# high level client only)
|
# high level client only)
|
||||||
self._name_owners: Dict[str, str] = {}
|
self._name_owners: dict[str, str] = {}
|
||||||
# used for the high level service
|
# used for the high level service
|
||||||
self._path_exports: Dict[str, list[ServiceInterface]] = {}
|
self._path_exports: dict[str, list[ServiceInterface]] = {}
|
||||||
self._bus_address = (
|
self._bus_address = (
|
||||||
parse_address(bus_address)
|
parse_address(bus_address)
|
||||||
if bus_address
|
if bus_address
|
||||||
@@ -156,7 +156,7 @@ class BaseMessageBus:
|
|||||||
self._name_owner_match_rule = "sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',path='/org/freedesktop/DBus',member='NameOwnerChanged'"
|
self._name_owner_match_rule = "sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',path='/org/freedesktop/DBus',member='NameOwnerChanged'"
|
||||||
# _match_rules: the keys are match rules and the values are ref counts
|
# _match_rules: the keys are match rules and the values are ref counts
|
||||||
# (used for the high level client only)
|
# (used for the high level client only)
|
||||||
self._match_rules: Dict[str, int] = {}
|
self._match_rules: dict[str, int] = {}
|
||||||
self._high_level_client_initialized = False
|
self._high_level_client_initialized = False
|
||||||
self._ProxyObject = ProxyObject
|
self._ProxyObject = ProxyObject
|
||||||
|
|
||||||
@@ -350,7 +350,7 @@ class BaseMessageBus:
|
|||||||
|
|
||||||
ServiceInterface._get_all_property_values(interface, get_properties_callback)
|
ServiceInterface._get_all_property_values(interface, get_properties_callback)
|
||||||
|
|
||||||
def _emit_interface_removed(self, path: str, removed_interfaces: List[str]) -> None:
|
def _emit_interface_removed(self, path: str, removed_interfaces: list[str]) -> None:
|
||||||
"""Emit the ``org.freedesktop.DBus.ObjectManager.InterfacesRemoved` signal.
|
"""Emit the ``org.freedesktop.DBus.ObjectManager.InterfacesRemoved` signal.
|
||||||
|
|
||||||
This signal is intended to be used to alert clients when
|
This signal is intended to be used to alert clients when
|
||||||
@@ -622,8 +622,8 @@ class BaseMessageBus:
|
|||||||
interface_name: str,
|
interface_name: str,
|
||||||
member: str,
|
member: str,
|
||||||
signature: str,
|
signature: str,
|
||||||
body: List[Any],
|
body: list[Any],
|
||||||
unix_fds: List[int] = [],
|
unix_fds: list[int] = [],
|
||||||
) -> None:
|
) -> None:
|
||||||
path = None
|
path = None
|
||||||
for p, ifaces in self._path_exports.items():
|
for p, ifaces in self._path_exports.items():
|
||||||
|
|||||||
@@ -3,9 +3,10 @@ import inspect
|
|||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
import xml.etree.ElementTree as ET
|
import xml.etree.ElementTree as ET
|
||||||
|
from collections.abc import Coroutine
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from functools import lru_cache
|
from functools import lru_cache
|
||||||
from typing import Callable, Coroutine, Dict, List, Optional, Type, Union
|
from typing import Callable, Dict, List, Optional, Type, Union
|
||||||
|
|
||||||
from . import introspection as intr
|
from . import introspection as intr
|
||||||
from . import message_bus
|
from . import message_bus
|
||||||
@@ -62,7 +63,7 @@ class BaseProxyInterface:
|
|||||||
self.path = path
|
self.path = path
|
||||||
self.introspection = introspection
|
self.introspection = introspection
|
||||||
self.bus = bus
|
self.bus = bus
|
||||||
self._signal_handlers: Dict[str, List[SignalHandler]] = {}
|
self._signal_handlers: dict[str, list[SignalHandler]] = {}
|
||||||
self._signal_match_rule = f"type='signal',sender={bus_name},interface={introspection.name},path={path}"
|
self._signal_match_rule = f"type='signal',sender={bus_name},interface={introspection.name},path={path}"
|
||||||
|
|
||||||
_underscorer1 = re.compile(r"(.)([A-Z][a-z]+)")
|
_underscorer1 = re.compile(r"(.)([A-Z][a-z]+)")
|
||||||
@@ -239,7 +240,7 @@ class BaseProxyObject:
|
|||||||
path: str,
|
path: str,
|
||||||
introspection: Union[intr.Node, str, ET.Element],
|
introspection: Union[intr.Node, str, ET.Element],
|
||||||
bus: "message_bus.BaseMessageBus",
|
bus: "message_bus.BaseMessageBus",
|
||||||
ProxyInterface: Type[BaseProxyInterface],
|
ProxyInterface: type[BaseProxyInterface],
|
||||||
) -> None:
|
) -> None:
|
||||||
assert_object_path_valid(path)
|
assert_object_path_valid(path)
|
||||||
assert_bus_name_valid(bus_name)
|
assert_bus_name_valid(bus_name)
|
||||||
@@ -330,7 +331,7 @@ class BaseProxyObject:
|
|||||||
self._interfaces[name] = interface
|
self._interfaces[name] = interface
|
||||||
return interface
|
return interface
|
||||||
|
|
||||||
def get_children(self) -> List["BaseProxyObject"]:
|
def get_children(self) -> list["BaseProxyObject"]:
|
||||||
"""Get the child nodes of this proxy object according to the introspection data."""
|
"""Get the child nodes of this proxy object according to the introspection data."""
|
||||||
if self._children is None:
|
if self._children is None:
|
||||||
self._children = [
|
self._children = [
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class SendReply:
|
|||||||
|
|
||||||
def _exit(
|
def _exit(
|
||||||
self,
|
self,
|
||||||
exc_type: Optional[Type[Exception]],
|
exc_type: Optional[type[Exception]],
|
||||||
exc_value: Optional[Exception],
|
exc_value: Optional[Exception],
|
||||||
tb: Optional[TracebackType],
|
tb: Optional[TracebackType],
|
||||||
) -> bool:
|
) -> bool:
|
||||||
@@ -49,7 +49,7 @@ class SendReply:
|
|||||||
|
|
||||||
def __exit__(
|
def __exit__(
|
||||||
self,
|
self,
|
||||||
exc_type: Optional[Type[Exception]],
|
exc_type: Optional[type[Exception]],
|
||||||
exc_value: Optional[Exception],
|
exc_value: Optional[Exception],
|
||||||
tb: Optional[TracebackType],
|
tb: Optional[TracebackType],
|
||||||
) -> bool:
|
) -> bool:
|
||||||
|
|||||||
@@ -317,7 +317,7 @@ def _real_fn_result_to_body(
|
|||||||
result: Optional[Any],
|
result: Optional[Any],
|
||||||
signature_tree: SignatureTree,
|
signature_tree: SignatureTree,
|
||||||
replace_fds: bool,
|
replace_fds: bool,
|
||||||
) -> Tuple[List[Any], List[int]]:
|
) -> tuple[list[Any], list[int]]:
|
||||||
out_len = len(signature_tree.types)
|
out_len = len(signature_tree.types)
|
||||||
if result is None:
|
if result is None:
|
||||||
final_result = []
|
final_result = []
|
||||||
@@ -362,13 +362,13 @@ class ServiceInterface:
|
|||||||
def __init__(self, name: str) -> None:
|
def __init__(self, name: str) -> None:
|
||||||
# TODO cannot be overridden by a dbus member
|
# TODO cannot be overridden by a dbus member
|
||||||
self.name = name
|
self.name = name
|
||||||
self.__methods: List[_Method] = []
|
self.__methods: list[_Method] = []
|
||||||
self.__properties: List[_Property] = []
|
self.__properties: list[_Property] = []
|
||||||
self.__signals: List[_Signal] = []
|
self.__signals: list[_Signal] = []
|
||||||
self.__buses = set()
|
self.__buses = set()
|
||||||
self.__handlers: Dict[
|
self.__handlers: dict[
|
||||||
BaseMessageBus,
|
BaseMessageBus,
|
||||||
Dict[_Method, Callable[[Message, Callable[[Message], None]], None]],
|
dict[_Method, Callable[[Message, Callable[[Message], None]], None]],
|
||||||
] = {}
|
] = {}
|
||||||
|
|
||||||
for name, member in inspect.getmembers(type(self)):
|
for name, member in inspect.getmembers(type(self)):
|
||||||
@@ -404,7 +404,7 @@ class ServiceInterface:
|
|||||||
)
|
)
|
||||||
|
|
||||||
def emit_properties_changed(
|
def emit_properties_changed(
|
||||||
self, changed_properties: Dict[str, Any], invalidated_properties: List[str] = []
|
self, changed_properties: dict[str, Any], invalidated_properties: list[str] = []
|
||||||
):
|
):
|
||||||
"""Emit the ``org.freedesktop.DBus.Properties.PropertiesChanged`` signal.
|
"""Emit the ``org.freedesktop.DBus.Properties.PropertiesChanged`` signal.
|
||||||
|
|
||||||
@@ -464,26 +464,26 @@ class ServiceInterface:
|
|||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _get_properties(interface: "ServiceInterface") -> List[_Property]:
|
def _get_properties(interface: "ServiceInterface") -> list[_Property]:
|
||||||
return interface.__properties
|
return interface.__properties
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _get_methods(interface: "ServiceInterface") -> List[_Method]:
|
def _get_methods(interface: "ServiceInterface") -> list[_Method]:
|
||||||
return interface.__methods
|
return interface.__methods
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _c_get_methods(interface: "ServiceInterface") -> List[_Method]:
|
def _c_get_methods(interface: "ServiceInterface") -> list[_Method]:
|
||||||
# _c_get_methods is used by the C code to get the methods for an
|
# _c_get_methods is used by the C code to get the methods for an
|
||||||
# interface
|
# interface
|
||||||
# https://github.com/cython/cython/issues/3327
|
# https://github.com/cython/cython/issues/3327
|
||||||
return interface.__methods
|
return interface.__methods
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _get_signals(interface: "ServiceInterface") -> List[_Signal]:
|
def _get_signals(interface: "ServiceInterface") -> list[_Signal]:
|
||||||
return interface.__signals
|
return interface.__signals
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _get_buses(interface: "ServiceInterface") -> Set["BaseMessageBus"]:
|
def _get_buses(interface: "ServiceInterface") -> set["BaseMessageBus"]:
|
||||||
return interface.__buses
|
return interface.__buses
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@@ -520,11 +520,11 @@ class ServiceInterface:
|
|||||||
del interface.__handlers[bus]
|
del interface.__handlers[bus]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _msg_body_to_args(msg: Message) -> List[Any]:
|
def _msg_body_to_args(msg: Message) -> list[Any]:
|
||||||
return ServiceInterface._c_msg_body_to_args(msg)
|
return ServiceInterface._c_msg_body_to_args(msg)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _c_msg_body_to_args(msg: Message) -> List[Any]:
|
def _c_msg_body_to_args(msg: Message) -> list[Any]:
|
||||||
# https://github.com/cython/cython/issues/3327
|
# https://github.com/cython/cython/issues/3327
|
||||||
if not signature_contains_type(msg.signature_tree, msg.body, "h"):
|
if not signature_contains_type(msg.signature_tree, msg.body, "h"):
|
||||||
return msg.body
|
return msg.body
|
||||||
@@ -541,7 +541,7 @@ class ServiceInterface:
|
|||||||
result: Optional[Any],
|
result: Optional[Any],
|
||||||
signature_tree: SignatureTree,
|
signature_tree: SignatureTree,
|
||||||
replace_fds: bool = True,
|
replace_fds: bool = True,
|
||||||
) -> Tuple[List[Any], List[int]]:
|
) -> tuple[list[Any], list[int]]:
|
||||||
return _real_fn_result_to_body(result, signature_tree, replace_fds)
|
return _real_fn_result_to_body(result, signature_tree, replace_fds)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@@ -549,7 +549,7 @@ class ServiceInterface:
|
|||||||
result: Optional[Any],
|
result: Optional[Any],
|
||||||
signature_tree: SignatureTree,
|
signature_tree: SignatureTree,
|
||||||
replace_fds: bool,
|
replace_fds: bool,
|
||||||
) -> Tuple[List[Any], List[int]]:
|
) -> tuple[list[Any], list[int]]:
|
||||||
"""The high level interfaces may return single values which may be
|
"""The high level interfaces may return single values which may be
|
||||||
wrapped in a list to be a message body. Also they may return fds
|
wrapped in a list to be a message body. Also they may return fds
|
||||||
directly for type 'h' which need to be put into an external list."""
|
directly for type 'h' which need to be put into an external list."""
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class SignatureType:
|
|||||||
def __init__(self, token: str) -> None:
|
def __init__(self, token: str) -> None:
|
||||||
"""Init a new SignatureType."""
|
"""Init a new SignatureType."""
|
||||||
self.token: str = token
|
self.token: str = token
|
||||||
self.children: List[SignatureType] = []
|
self.children: list[SignatureType] = []
|
||||||
self._signature: Optional[str] = None
|
self._signature: Optional[str] = None
|
||||||
|
|
||||||
def __eq__(self, other: Any) -> bool:
|
def __eq__(self, other: Any) -> bool:
|
||||||
@@ -60,7 +60,7 @@ class SignatureType:
|
|||||||
return self._signature
|
return self._signature
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _parse_next(signature: str) -> Tuple["SignatureType", str]:
|
def _parse_next(signature: str) -> tuple["SignatureType", str]:
|
||||||
if not signature:
|
if not signature:
|
||||||
raise InvalidSignatureError("Cannot parse an empty signature")
|
raise InvalidSignatureError("Cannot parse an empty signature")
|
||||||
|
|
||||||
@@ -295,7 +295,7 @@ class SignatureType:
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
validators: Dict[str, Callable[["SignatureType", Any], None]] = {
|
validators: dict[str, Callable[["SignatureType", Any], None]] = {
|
||||||
"y": _verify_byte,
|
"y": _verify_byte,
|
||||||
"b": _verify_boolean,
|
"b": _verify_boolean,
|
||||||
"n": _verify_int16,
|
"n": _verify_int16,
|
||||||
@@ -336,7 +336,7 @@ class SignatureTree:
|
|||||||
def __init__(self, signature: str = "") -> None:
|
def __init__(self, signature: str = "") -> None:
|
||||||
self.signature = signature
|
self.signature = signature
|
||||||
|
|
||||||
self.types: List[SignatureType] = []
|
self.types: list[SignatureType] = []
|
||||||
|
|
||||||
if len(signature) > 0xFF:
|
if len(signature) > 0xFF:
|
||||||
raise InvalidSignatureError("A signature must be less than 256 characters")
|
raise InvalidSignatureError("A signature must be less than 256 characters")
|
||||||
@@ -350,7 +350,7 @@ class SignatureTree:
|
|||||||
return self.signature == other.signature
|
return self.signature == other.signature
|
||||||
return super().__eq__(other)
|
return super().__eq__(other)
|
||||||
|
|
||||||
def verify(self, body: List[Any]) -> bool:
|
def verify(self, body: list[Any]) -> bool:
|
||||||
"""Verifies that the give body matches this signature tree
|
"""Verifies that the give body matches this signature tree
|
||||||
|
|
||||||
:param body: the body to verify for this tree
|
:param body: the body to verify for this tree
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ with open(os.path.dirname(__file__) + "/data/get_managed_objects.hex") as fp:
|
|||||||
get_managed_objects_msg = fp.read()
|
get_managed_objects_msg = fp.read()
|
||||||
|
|
||||||
|
|
||||||
def json_to_message(message: Dict[str, Any]) -> Message:
|
def json_to_message(message: dict[str, Any]) -> Message:
|
||||||
copy = dict(message)
|
copy = dict(message)
|
||||||
if "message_type" in copy:
|
if "message_type" in copy:
|
||||||
copy["message_type"] = MessageType(copy["message_type"])
|
copy["message_type"] = MessageType(copy["message_type"])
|
||||||
|
|||||||
Reference in New Issue
Block a user