feat: add additional typing (#93)

This commit is contained in:
J. Nick Koston 2022-10-09 09:29:31 -10:00 committed by GitHub
parent 2d4561cff0
commit 7326bdf097
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 39 additions and 42 deletions

View File

@ -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

View File

@ -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
) )

View File

@ -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