Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add additional typing #93

Merged
merged 3 commits into from
Oct 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/dbus_fast/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ class PropertyAccess(Enum):
WRITE = "write" #: The property is writeonly.
READWRITE = "readwrite" #: The property can be read or written to.

def readable(self):
def readable(self) -> bool:
"""Get whether the property can be read."""
return self == PropertyAccess.READ or self == PropertyAccess.READWRITE

def writable(self):
def writable(self) -> bool:
"""Get whether the property can be written to."""
return self == PropertyAccess.WRITE or self == PropertyAccess.READWRITE

Expand Down
67 changes: 32 additions & 35 deletions src/dbus_fast/signature.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
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 .validators import is_object_path_valid
Expand All @@ -26,15 +26,14 @@ class to parse signatures.
def __init__(self, token: str) -> None:
self.token = token
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:
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({":
return self.token

Expand All @@ -58,9 +57,9 @@ def signature(self) -> str:
return self._signature

@staticmethod
def _parse_next(signature):
def _parse_next(signature: str) -> Tuple["SignatureType", str]:
if not signature:
return (None, "")
raise InvalidSignatureError("Cannot parse an empty signature")

token = signature[0]

Expand Down Expand Up @@ -103,7 +102,7 @@ def _parse_next(signature):
# basic type
return (SignatureType(token), signature[1:])

def _verify_byte(self, body):
def _verify_byte(self, body: Any) -> None:
BYTE_MIN = 0x00
BYTE_MAX = 0xFF
if not isinstance(body, int):
Expand All @@ -115,13 +114,13 @@ def _verify_byte(self, body):
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):
raise SignatureBodyMismatchError(
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_MAX = 0x7FFF
if not isinstance(body, int):
Expand All @@ -133,7 +132,7 @@ def _verify_int16(self, body):
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_MAX = 0xFFFF
if not isinstance(body, int):
Expand All @@ -145,7 +144,7 @@ def _verify_uint16(self, body):
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_MAX = 0x7FFFFFFF
if not isinstance(body, int):
Expand All @@ -157,7 +156,7 @@ def _verify_int32(self, body):
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_MAX = 0xFFFFFFFF
if not isinstance(body, int):
Expand All @@ -169,7 +168,7 @@ def _verify_uint32(self, body):
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_MIN = -INT64_MAX - 1
if not isinstance(body, int):
Expand All @@ -181,7 +180,7 @@ def _verify_int64(self, body):
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_MAX = 18446744073709551615
if not isinstance(body, int):
Expand All @@ -193,33 +192,33 @@ def _verify_uint64(self, body):
f'DBus UINT64 type "t" must be between {UINT64_MIN} and {UINT64_MAX}'
)

def _verify_double(self, body):
if not isinstance(body, float) and not isinstance(body, int):
def _verify_double(self, body: Any) -> None:
if not isinstance(body, (float, int)):
raise SignatureBodyMismatchError(
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:
self._verify_uint32(body)
except SignatureBodyMismatchError:
raise SignatureBodyMismatchError(
'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):
raise SignatureBodyMismatchError(
'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):
raise SignatureBodyMismatchError(
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
if not isinstance(body, str):
raise SignatureBodyMismatchError(
Expand All @@ -230,7 +229,7 @@ def _verify_signature(self, body):
'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]

if child_type.token == "{":
Expand All @@ -255,7 +254,7 @@ def _verify_array(self, body):
for member in body:
child_type.verify(member)

def _verify_struct(self, body):
def _verify_struct(self, body: Any) -> None:
# TODO allow tuples
if not isinstance(body, list):
raise SignatureBodyMismatchError(
Expand All @@ -270,7 +269,7 @@ def _verify_struct(self, body):
for i, member in enumerate(body):
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
if not isinstance(body, Variant):
raise SignatureBodyMismatchError(
Expand All @@ -294,7 +293,7 @@ def verify(self, body: Any) -> bool:

return True

validators = {
validators: Dict[str, Callable[["SignatureType", Any], None]] = {
"y": _verify_byte,
"b": _verify_boolean,
"n": _verify_int16,
Expand Down Expand Up @@ -332,7 +331,7 @@ class SignatureTree:

__slots__ = ("signature", "types")

def __init__(self, signature: str = ""):
def __init__(self, signature: str = "") -> None:
self.signature = signature

self.types: List[SignatureType] = []
Expand All @@ -344,13 +343,12 @@ def __init__(self, signature: str = ""):
(type_, signature) = SignatureType._parse_next(signature)
self.types.append(type_)

def __eq__(self, other):
def __eq__(self, other: Any) -> bool:
if type(other) is SignatureTree:
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

:param body: the body to verify for this tree
Expand Down Expand Up @@ -433,13 +431,12 @@ def __init__(
self.signature = signature_str
self.value = value

def __eq__(self, other):
def __eq__(self, other: Any) -> bool:
if type(other) is Variant:
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(
self.type.signature, self.value
)
Expand Down
10 changes: 5 additions & 5 deletions src/dbus_fast/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def is_bus_name_valid(name: str) -> bool:
:rtype: bool
"""
if not isinstance(name, str):
return False
return False # type: ignore[unreachable]

if not name or len(name) > 255:
return False
Expand Down Expand Up @@ -62,7 +62,7 @@ def is_object_path_valid(path: str) -> bool:
:rtype: bool
"""
if not isinstance(path, str):
return False
return False # type: ignore[unreachable]

if not path:
return False
Expand Down Expand Up @@ -93,7 +93,7 @@ def is_interface_name_valid(name: str) -> bool:
:rtype: bool
"""
if not isinstance(name, str):
return False
return False # type: ignore[unreachable]

if not name or len(name) > 255:
return False
Expand Down Expand Up @@ -124,7 +124,7 @@ def is_member_name_valid(member: str) -> bool:
:rtype: bool
"""
if not isinstance(member, str):
return False
return False # type: ignore[unreachable]

if not member or len(member) > 255:
return False
Expand Down Expand Up @@ -180,7 +180,7 @@ def assert_interface_name_valid(name: str) -> None:
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.

.. seealso:: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-member
Expand Down