feat: add additional typing (#93)
This commit is contained in:
parent
2d4561cff0
commit
7326bdf097
@ -69,11 +69,11 @@ class PropertyAccess(Enum):
|
|||||||
WRITE = "write" #: The property is writeonly.
|
WRITE = "write" #: The property is writeonly.
|
||||||
READWRITE = "readwrite" #: The property can be read or written to.
|
READWRITE = "readwrite" #: The property can be read or written to.
|
||||||
|
|
||||||
def readable(self):
|
def readable(self) -> bool:
|
||||||
"""Get whether the property can be read."""
|
"""Get whether the property can be read."""
|
||||||
return self == PropertyAccess.READ or self == PropertyAccess.READWRITE
|
return self == PropertyAccess.READ or self == PropertyAccess.READWRITE
|
||||||
|
|
||||||
def writable(self):
|
def writable(self) -> bool:
|
||||||
"""Get whether the property can be written to."""
|
"""Get whether the property can be written to."""
|
||||||
return self == PropertyAccess.WRITE or self == PropertyAccess.READWRITE
|
return self == PropertyAccess.WRITE or self == PropertyAccess.READWRITE
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
from functools import lru_cache
|
from functools import lru_cache
|
||||||
from typing import Any, List, Union
|
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
|
||||||
|
|
||||||
from .errors import InvalidSignatureError, SignatureBodyMismatchError
|
from .errors import InvalidSignatureError, SignatureBodyMismatchError
|
||||||
from .validators import is_object_path_valid
|
from .validators import is_object_path_valid
|
||||||
@ -26,15 +26,14 @@ class SignatureType:
|
|||||||
def __init__(self, token: str) -> None:
|
def __init__(self, token: str) -> None:
|
||||||
self.token = token
|
self.token = token
|
||||||
self.children: List[SignatureType] = []
|
self.children: List[SignatureType] = []
|
||||||
self._signature = None
|
self._signature: Optional[str] = None
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other: Any) -> bool:
|
||||||
if type(other) is SignatureType:
|
if type(other) is SignatureType:
|
||||||
return self.signature == other.signature
|
return self.signature == other.signature
|
||||||
else:
|
return super().__eq__(other)
|
||||||
return super().__eq__(other)
|
|
||||||
|
|
||||||
def _collapse(self):
|
def _collapse(self) -> str:
|
||||||
if self.token not in "a({":
|
if self.token not in "a({":
|
||||||
return self.token
|
return self.token
|
||||||
|
|
||||||
@ -58,9 +57,9 @@ class SignatureType:
|
|||||||
return self._signature
|
return self._signature
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _parse_next(signature):
|
def _parse_next(signature: str) -> Tuple["SignatureType", str]:
|
||||||
if not signature:
|
if not signature:
|
||||||
return (None, "")
|
raise InvalidSignatureError("Cannot parse an empty signature")
|
||||||
|
|
||||||
token = signature[0]
|
token = signature[0]
|
||||||
|
|
||||||
@ -103,7 +102,7 @@ class SignatureType:
|
|||||||
# basic type
|
# basic type
|
||||||
return (SignatureType(token), signature[1:])
|
return (SignatureType(token), signature[1:])
|
||||||
|
|
||||||
def _verify_byte(self, body):
|
def _verify_byte(self, body: Any) -> None:
|
||||||
BYTE_MIN = 0x00
|
BYTE_MIN = 0x00
|
||||||
BYTE_MAX = 0xFF
|
BYTE_MAX = 0xFF
|
||||||
if not isinstance(body, int):
|
if not isinstance(body, int):
|
||||||
@ -115,13 +114,13 @@ class SignatureType:
|
|||||||
f"DBus BYTE type must be between {BYTE_MIN} and {BYTE_MAX}"
|
f"DBus BYTE type must be between {BYTE_MIN} and {BYTE_MAX}"
|
||||||
)
|
)
|
||||||
|
|
||||||
def _verify_boolean(self, body):
|
def _verify_boolean(self, body: Any) -> None:
|
||||||
if not isinstance(body, bool):
|
if not isinstance(body, bool):
|
||||||
raise SignatureBodyMismatchError(
|
raise SignatureBodyMismatchError(
|
||||||
f'DBus BOOLEAN type "b" must be Python type "bool", got {type(body)}'
|
f'DBus BOOLEAN type "b" must be Python type "bool", got {type(body)}'
|
||||||
)
|
)
|
||||||
|
|
||||||
def _verify_int16(self, body):
|
def _verify_int16(self, body: Any) -> None:
|
||||||
INT16_MIN = -0x7FFF - 1
|
INT16_MIN = -0x7FFF - 1
|
||||||
INT16_MAX = 0x7FFF
|
INT16_MAX = 0x7FFF
|
||||||
if not isinstance(body, int):
|
if not isinstance(body, int):
|
||||||
@ -133,7 +132,7 @@ class SignatureType:
|
|||||||
f'DBus INT16 type "n" must be between {INT16_MIN} and {INT16_MAX}'
|
f'DBus INT16 type "n" must be between {INT16_MIN} and {INT16_MAX}'
|
||||||
)
|
)
|
||||||
|
|
||||||
def _verify_uint16(self, body):
|
def _verify_uint16(self, body: Any) -> None:
|
||||||
UINT16_MIN = 0
|
UINT16_MIN = 0
|
||||||
UINT16_MAX = 0xFFFF
|
UINT16_MAX = 0xFFFF
|
||||||
if not isinstance(body, int):
|
if not isinstance(body, int):
|
||||||
@ -145,7 +144,7 @@ class SignatureType:
|
|||||||
f'DBus UINT16 type "q" must be between {UINT16_MIN} and {UINT16_MAX}'
|
f'DBus UINT16 type "q" must be between {UINT16_MIN} and {UINT16_MAX}'
|
||||||
)
|
)
|
||||||
|
|
||||||
def _verify_int32(self, body):
|
def _verify_int32(self, body: int) -> None:
|
||||||
INT32_MIN = -0x7FFFFFFF - 1
|
INT32_MIN = -0x7FFFFFFF - 1
|
||||||
INT32_MAX = 0x7FFFFFFF
|
INT32_MAX = 0x7FFFFFFF
|
||||||
if not isinstance(body, int):
|
if not isinstance(body, int):
|
||||||
@ -157,7 +156,7 @@ class SignatureType:
|
|||||||
f'DBus INT32 type "i" must be between {INT32_MIN} and {INT32_MAX}'
|
f'DBus INT32 type "i" must be between {INT32_MIN} and {INT32_MAX}'
|
||||||
)
|
)
|
||||||
|
|
||||||
def _verify_uint32(self, body):
|
def _verify_uint32(self, body: Any) -> None:
|
||||||
UINT32_MIN = 0
|
UINT32_MIN = 0
|
||||||
UINT32_MAX = 0xFFFFFFFF
|
UINT32_MAX = 0xFFFFFFFF
|
||||||
if not isinstance(body, int):
|
if not isinstance(body, int):
|
||||||
@ -169,7 +168,7 @@ class SignatureType:
|
|||||||
f'DBus UINT32 type "u" must be between {UINT32_MIN} and {UINT32_MAX}'
|
f'DBus UINT32 type "u" must be between {UINT32_MIN} and {UINT32_MAX}'
|
||||||
)
|
)
|
||||||
|
|
||||||
def _verify_int64(self, body):
|
def _verify_int64(self, body: Any) -> None:
|
||||||
INT64_MAX = 9223372036854775807
|
INT64_MAX = 9223372036854775807
|
||||||
INT64_MIN = -INT64_MAX - 1
|
INT64_MIN = -INT64_MAX - 1
|
||||||
if not isinstance(body, int):
|
if not isinstance(body, int):
|
||||||
@ -181,7 +180,7 @@ class SignatureType:
|
|||||||
f'DBus INT64 type "x" must be between {INT64_MIN} and {INT64_MAX}'
|
f'DBus INT64 type "x" must be between {INT64_MIN} and {INT64_MAX}'
|
||||||
)
|
)
|
||||||
|
|
||||||
def _verify_uint64(self, body):
|
def _verify_uint64(self, body: Any) -> None:
|
||||||
UINT64_MIN = 0
|
UINT64_MIN = 0
|
||||||
UINT64_MAX = 18446744073709551615
|
UINT64_MAX = 18446744073709551615
|
||||||
if not isinstance(body, int):
|
if not isinstance(body, int):
|
||||||
@ -193,13 +192,13 @@ class SignatureType:
|
|||||||
f'DBus UINT64 type "t" must be between {UINT64_MIN} and {UINT64_MAX}'
|
f'DBus UINT64 type "t" must be between {UINT64_MIN} and {UINT64_MAX}'
|
||||||
)
|
)
|
||||||
|
|
||||||
def _verify_double(self, body):
|
def _verify_double(self, body: Any) -> None:
|
||||||
if not isinstance(body, float) and not isinstance(body, int):
|
if not isinstance(body, (float, int)):
|
||||||
raise SignatureBodyMismatchError(
|
raise SignatureBodyMismatchError(
|
||||||
f'DBus DOUBLE type "d" must be Python type "float" or "int", got {type(body)}'
|
f'DBus DOUBLE type "d" must be Python type "float" or "int", got {type(body)}'
|
||||||
)
|
)
|
||||||
|
|
||||||
def _verify_unix_fd(self, body):
|
def _verify_unix_fd(self, body: Any) -> None:
|
||||||
try:
|
try:
|
||||||
self._verify_uint32(body)
|
self._verify_uint32(body)
|
||||||
except SignatureBodyMismatchError:
|
except SignatureBodyMismatchError:
|
||||||
@ -207,19 +206,19 @@ class SignatureType:
|
|||||||
'DBus UNIX_FD type "h" must be a valid UINT32'
|
'DBus UNIX_FD type "h" must be a valid UINT32'
|
||||||
)
|
)
|
||||||
|
|
||||||
def _verify_object_path(self, body):
|
def _verify_object_path(self, body: Any) -> None:
|
||||||
if not is_object_path_valid(body):
|
if not is_object_path_valid(body):
|
||||||
raise SignatureBodyMismatchError(
|
raise SignatureBodyMismatchError(
|
||||||
'DBus OBJECT_PATH type "o" must be a valid object path'
|
'DBus OBJECT_PATH type "o" must be a valid object path'
|
||||||
)
|
)
|
||||||
|
|
||||||
def _verify_string(self, body):
|
def _verify_string(self, body: Any) -> None:
|
||||||
if not isinstance(body, str):
|
if not isinstance(body, str):
|
||||||
raise SignatureBodyMismatchError(
|
raise SignatureBodyMismatchError(
|
||||||
f'DBus STRING type "s" must be Python type "str", got {type(body)}'
|
f'DBus STRING type "s" must be Python type "str", got {type(body)}'
|
||||||
)
|
)
|
||||||
|
|
||||||
def _verify_signature(self, body):
|
def _verify_signature(self, body: Any) -> None:
|
||||||
# I guess we could run it through the SignatureTree parser instead
|
# I guess we could run it through the SignatureTree parser instead
|
||||||
if not isinstance(body, str):
|
if not isinstance(body, str):
|
||||||
raise SignatureBodyMismatchError(
|
raise SignatureBodyMismatchError(
|
||||||
@ -230,7 +229,7 @@ class SignatureType:
|
|||||||
'DBus SIGNATURE type "g" must be less than 256 bytes'
|
'DBus SIGNATURE type "g" must be less than 256 bytes'
|
||||||
)
|
)
|
||||||
|
|
||||||
def _verify_array(self, body):
|
def _verify_array(self, body: Any) -> None:
|
||||||
child_type = self.children[0]
|
child_type = self.children[0]
|
||||||
|
|
||||||
if child_type.token == "{":
|
if child_type.token == "{":
|
||||||
@ -255,7 +254,7 @@ class SignatureType:
|
|||||||
for member in body:
|
for member in body:
|
||||||
child_type.verify(member)
|
child_type.verify(member)
|
||||||
|
|
||||||
def _verify_struct(self, body):
|
def _verify_struct(self, body: Any) -> None:
|
||||||
# TODO allow tuples
|
# TODO allow tuples
|
||||||
if not isinstance(body, list):
|
if not isinstance(body, list):
|
||||||
raise SignatureBodyMismatchError(
|
raise SignatureBodyMismatchError(
|
||||||
@ -270,7 +269,7 @@ class SignatureType:
|
|||||||
for i, member in enumerate(body):
|
for i, member in enumerate(body):
|
||||||
self.children[i].verify(member)
|
self.children[i].verify(member)
|
||||||
|
|
||||||
def _verify_variant(self, body):
|
def _verify_variant(self, body: Any) -> None:
|
||||||
# a variant signature and value is valid by construction
|
# a variant signature and value is valid by construction
|
||||||
if not isinstance(body, Variant):
|
if not isinstance(body, Variant):
|
||||||
raise SignatureBodyMismatchError(
|
raise SignatureBodyMismatchError(
|
||||||
@ -294,7 +293,7 @@ class SignatureType:
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
validators = {
|
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,
|
||||||
@ -332,7 +331,7 @@ class SignatureTree:
|
|||||||
|
|
||||||
__slots__ = ("signature", "types")
|
__slots__ = ("signature", "types")
|
||||||
|
|
||||||
def __init__(self, signature: str = ""):
|
def __init__(self, signature: str = "") -> None:
|
||||||
self.signature = signature
|
self.signature = signature
|
||||||
|
|
||||||
self.types: List[SignatureType] = []
|
self.types: List[SignatureType] = []
|
||||||
@ -344,13 +343,12 @@ class SignatureTree:
|
|||||||
(type_, signature) = SignatureType._parse_next(signature)
|
(type_, signature) = SignatureType._parse_next(signature)
|
||||||
self.types.append(type_)
|
self.types.append(type_)
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other: Any) -> bool:
|
||||||
if type(other) is SignatureTree:
|
if type(other) is SignatureTree:
|
||||||
return self.signature == other.signature
|
return self.signature == other.signature
|
||||||
else:
|
return super().__eq__(other)
|
||||||
return super().__eq__(other)
|
|
||||||
|
|
||||||
def verify(self, body: List[Any]):
|
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
|
||||||
@ -433,13 +431,12 @@ class Variant:
|
|||||||
self.signature = signature_str
|
self.signature = signature_str
|
||||||
self.value = value
|
self.value = value
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other: Any) -> bool:
|
||||||
if type(other) is Variant:
|
if type(other) is Variant:
|
||||||
return self.signature == other.signature and self.value == other.value
|
return self.signature == other.signature and self.value == other.value
|
||||||
else:
|
return super().__eq__(other)
|
||||||
return super().__eq__(other)
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self) -> str:
|
||||||
return "<dbus_fast.signature.Variant ('{}', {})>".format(
|
return "<dbus_fast.signature.Variant ('{}', {})>".format(
|
||||||
self.type.signature, self.value
|
self.type.signature, self.value
|
||||||
)
|
)
|
||||||
|
|||||||
@ -27,7 +27,7 @@ def is_bus_name_valid(name: str) -> bool:
|
|||||||
:rtype: bool
|
:rtype: bool
|
||||||
"""
|
"""
|
||||||
if not isinstance(name, str):
|
if not isinstance(name, str):
|
||||||
return False
|
return False # type: ignore[unreachable]
|
||||||
|
|
||||||
if not name or len(name) > 255:
|
if not name or len(name) > 255:
|
||||||
return False
|
return False
|
||||||
@ -62,7 +62,7 @@ def is_object_path_valid(path: str) -> bool:
|
|||||||
:rtype: bool
|
:rtype: bool
|
||||||
"""
|
"""
|
||||||
if not isinstance(path, str):
|
if not isinstance(path, str):
|
||||||
return False
|
return False # type: ignore[unreachable]
|
||||||
|
|
||||||
if not path:
|
if not path:
|
||||||
return False
|
return False
|
||||||
@ -93,7 +93,7 @@ def is_interface_name_valid(name: str) -> bool:
|
|||||||
:rtype: bool
|
:rtype: bool
|
||||||
"""
|
"""
|
||||||
if not isinstance(name, str):
|
if not isinstance(name, str):
|
||||||
return False
|
return False # type: ignore[unreachable]
|
||||||
|
|
||||||
if not name or len(name) > 255:
|
if not name or len(name) > 255:
|
||||||
return False
|
return False
|
||||||
@ -124,7 +124,7 @@ def is_member_name_valid(member: str) -> bool:
|
|||||||
:rtype: bool
|
:rtype: bool
|
||||||
"""
|
"""
|
||||||
if not isinstance(member, str):
|
if not isinstance(member, str):
|
||||||
return False
|
return False # type: ignore[unreachable]
|
||||||
|
|
||||||
if not member or len(member) > 255:
|
if not member or len(member) > 255:
|
||||||
return False
|
return False
|
||||||
@ -180,7 +180,7 @@ def assert_interface_name_valid(name: str) -> None:
|
|||||||
raise InvalidInterfaceNameError(name)
|
raise InvalidInterfaceNameError(name)
|
||||||
|
|
||||||
|
|
||||||
def assert_member_name_valid(member) -> None:
|
def assert_member_name_valid(member: str) -> None:
|
||||||
"""Raise an error if this is not a valid member name.
|
"""Raise an error if this is not a valid member name.
|
||||||
|
|
||||||
.. seealso:: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-member
|
.. seealso:: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-member
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user