feat: add cython extension for signature (#72)
This commit is contained in:
1
build.py
1
build.py
@@ -22,6 +22,7 @@ def build(setup_kwargs):
|
|||||||
dict(
|
dict(
|
||||||
ext_modules=cythonize(
|
ext_modules=cythonize(
|
||||||
[
|
[
|
||||||
|
"src/dbus_fast/signature.py",
|
||||||
"src/dbus_fast/unpack.py",
|
"src/dbus_fast/unpack.py",
|
||||||
"src/dbus_fast/_private/marshaller.py",
|
"src/dbus_fast/_private/marshaller.py",
|
||||||
"src/dbus_fast/_private/unmarshaller.py",
|
"src/dbus_fast/_private/unmarshaller.py",
|
||||||
|
|||||||
@@ -9,14 +9,13 @@ cdef class Marshaller:
|
|||||||
cdef bytearray _buf
|
cdef bytearray _buf
|
||||||
cdef object body
|
cdef object body
|
||||||
|
|
||||||
|
|
||||||
@cython.locals(
|
@cython.locals(
|
||||||
offset=cython.ulong,
|
offset=cython.ulong,
|
||||||
)
|
)
|
||||||
cpdef int align(self, unsigned long n)
|
cpdef int align(self, unsigned long n)
|
||||||
|
|
||||||
|
|
||||||
@cython.locals(
|
@cython.locals(
|
||||||
|
value_len=cython.uint,
|
||||||
signature_len=cython.uint,
|
signature_len=cython.uint,
|
||||||
written=cython.uint,
|
written=cython.uint,
|
||||||
)
|
)
|
||||||
@@ -26,11 +25,13 @@ cdef class Marshaller:
|
|||||||
array_len=cython.uint,
|
array_len=cython.uint,
|
||||||
written=cython.uint,
|
written=cython.uint,
|
||||||
array_len_packed=cython.bytes,
|
array_len_packed=cython.bytes,
|
||||||
|
i=cython.uint,
|
||||||
)
|
)
|
||||||
cpdef write_array(self, object array, object type)
|
cpdef write_array(self, object array, object type)
|
||||||
|
|
||||||
@cython.locals(
|
@cython.locals(
|
||||||
written=cython.uint,
|
written=cython.uint,
|
||||||
|
i=cython.uint,
|
||||||
)
|
)
|
||||||
cpdef write_struct(self, object array, object type)
|
cpdef write_struct(self, object array, object type)
|
||||||
|
|
||||||
@@ -39,9 +40,14 @@ cdef class Marshaller:
|
|||||||
)
|
)
|
||||||
cpdef write_single(self, object type_, object body)
|
cpdef write_single(self, object type_, object body)
|
||||||
|
|
||||||
|
@cython.locals(
|
||||||
|
written=cython.uint,
|
||||||
|
)
|
||||||
|
cpdef write_dict_entry(self, object type_, object body)
|
||||||
|
|
||||||
cpdef marshall(self)
|
cpdef marshall(self)
|
||||||
|
|
||||||
@cython.locals(
|
@cython.locals(
|
||||||
offset=cython.ulong,
|
offset=cython.ulong,
|
||||||
)
|
)
|
||||||
cpdef _construct_buffer(self)
|
cdef _construct_buffer(self)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from struct import Struct, error
|
from struct import Struct, error
|
||||||
from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple
|
from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple
|
||||||
|
|
||||||
from ..signature import SignatureTree, SignatureType, Variant
|
from ..signature import SignatureType, Variant, get_signature_tree
|
||||||
|
|
||||||
PACK_UINT32 = Struct("<I").pack
|
PACK_UINT32 = Struct("<I").pack
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ class Marshaller:
|
|||||||
|
|
||||||
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 = SignatureTree._get(signature)
|
self.signature_tree = get_signature_tree(signature)
|
||||||
self._buf = bytearray()
|
self._buf = bytearray()
|
||||||
self.body = body
|
self.body = body
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ cdef unsigned int BIG_ENDIAN
|
|||||||
cdef str UINT32_CAST
|
cdef str UINT32_CAST
|
||||||
cdef object UINT32_SIGNATURE
|
cdef object UINT32_SIGNATURE
|
||||||
|
|
||||||
|
cdef class MarshallerStreamEndError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
cdef class Unmarshaller:
|
cdef class Unmarshaller:
|
||||||
|
|
||||||
cdef object _unix_fds
|
cdef object _unix_fds
|
||||||
@@ -33,18 +36,20 @@ cdef class Unmarshaller:
|
|||||||
|
|
||||||
cpdef reset(self)
|
cpdef reset(self)
|
||||||
|
|
||||||
|
cdef read_sock(self, unsigned long length)
|
||||||
|
|
||||||
@cython.locals(
|
@cython.locals(
|
||||||
start_len=cython.ulong,
|
start_len=cython.ulong,
|
||||||
missing_bytes=cython.ulong
|
missing_bytes=cython.ulong
|
||||||
)
|
)
|
||||||
cpdef read_to_pos(self, unsigned long pos)
|
cdef read_to_pos(self, unsigned long pos)
|
||||||
|
|
||||||
cpdef read_uint32_cast(self, object type_)
|
cpdef read_uint32_cast(self, object type_)
|
||||||
|
|
||||||
@cython.locals(
|
@cython.locals(
|
||||||
buf_bytes=cython.bytearray,
|
buf_bytes=cython.bytearray,
|
||||||
)
|
)
|
||||||
cpdef read_string_cast(self, type_ = *)
|
cpdef read_string_cast(self, object type_)
|
||||||
|
|
||||||
@cython.locals(
|
@cython.locals(
|
||||||
beginning_pos=cython.ulong,
|
beginning_pos=cython.ulong,
|
||||||
@@ -56,16 +61,16 @@ cdef class Unmarshaller:
|
|||||||
o=cython.ulong,
|
o=cython.ulong,
|
||||||
signature_len=cython.uint,
|
signature_len=cython.uint,
|
||||||
)
|
)
|
||||||
cpdef read_signature(self, type_ = *)
|
cpdef read_signature(self, object type_)
|
||||||
|
|
||||||
@cython.locals(
|
@cython.locals(
|
||||||
endian=cython.uint,
|
endian=cython.uint,
|
||||||
protocol_version=cython.uint,
|
protocol_version=cython.uint,
|
||||||
can_cast=cython.bint
|
can_cast=cython.bint
|
||||||
)
|
)
|
||||||
cpdef _read_header(self)
|
cdef _read_header(self)
|
||||||
|
|
||||||
cpdef _read_body(self)
|
cdef _read_body(self)
|
||||||
|
|
||||||
cpdef unmarshall(self)
|
cpdef unmarshall(self)
|
||||||
|
|
||||||
@@ -74,4 +79,4 @@ cdef class Unmarshaller:
|
|||||||
o=cython.ulong,
|
o=cython.ulong,
|
||||||
signature_len=cython.uint,
|
signature_len=cython.uint,
|
||||||
)
|
)
|
||||||
cpdef header_fields(self, unsigned int header_length)
|
cdef header_fields(self, unsigned int header_length)
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ import io
|
|||||||
import socket
|
import socket
|
||||||
import sys
|
import sys
|
||||||
from struct import Struct
|
from struct import Struct
|
||||||
from typing import Any, Callable, Dict, List, Optional, Tuple
|
from typing import Any, Callable, Dict, List, Tuple
|
||||||
|
|
||||||
from ..constants import MESSAGE_FLAG_MAP, MESSAGE_TYPE_MAP, MessageFlag, MessageType
|
from ..constants import MESSAGE_FLAG_MAP, MESSAGE_TYPE_MAP
|
||||||
from ..errors import InvalidMessageError
|
from ..errors import InvalidMessageError
|
||||||
from ..message import Message
|
from ..message import Message
|
||||||
from ..signature import SignatureTree, SignatureType, Variant
|
from ..signature import SignatureType, Variant, get_signature_tree
|
||||||
from .constants import (
|
from .constants import (
|
||||||
BIG_ENDIAN,
|
BIG_ENDIAN,
|
||||||
HEADER_NAME_MAP,
|
HEADER_NAME_MAP,
|
||||||
@@ -28,7 +28,7 @@ UNPACK_LENGTHS = {BIG_ENDIAN: Struct(">III"), LITTLE_ENDIAN: Struct("<III")}
|
|||||||
UINT32_CAST = "I"
|
UINT32_CAST = "I"
|
||||||
UINT32_SIZE = 4
|
UINT32_SIZE = 4
|
||||||
UINT32_DBUS_TYPE = "u"
|
UINT32_DBUS_TYPE = "u"
|
||||||
UINT32_SIGNATURE = SignatureTree._get(UINT32_DBUS_TYPE).types[0]
|
UINT32_SIGNATURE = get_signature_tree(UINT32_DBUS_TYPE).types[0]
|
||||||
|
|
||||||
DBUS_TO_CTYPE = {
|
DBUS_TO_CTYPE = {
|
||||||
"y": ("B", 1), # byte
|
"y": ("B", 1), # byte
|
||||||
@@ -236,14 +236,14 @@ class Unmarshaller:
|
|||||||
if len(data) + start_len != pos:
|
if len(data) + start_len != pos:
|
||||||
raise MarshallerStreamEndError()
|
raise MarshallerStreamEndError()
|
||||||
|
|
||||||
def read_uint32_cast(self, signature: SignatureType) -> Any:
|
def read_uint32_cast(self, type_: SignatureType) -> Any:
|
||||||
self._pos += UINT32_SIZE + (-self._pos & (UINT32_SIZE - 1)) # align
|
self._pos += UINT32_SIZE + (-self._pos & (UINT32_SIZE - 1)) # align
|
||||||
return self._view[self._pos - UINT32_SIZE : self._pos].cast(UINT32_CAST)[0]
|
return self._view[self._pos - UINT32_SIZE : self._pos].cast(UINT32_CAST)[0]
|
||||||
|
|
||||||
def read_boolean(self, type_=None) -> bool:
|
def read_boolean(self, type_: SignatureType) -> bool:
|
||||||
return bool(self._readers[UINT32_SIGNATURE.token](self, UINT32_SIGNATURE))
|
return bool(self._readers[UINT32_SIGNATURE.token](self, UINT32_SIGNATURE))
|
||||||
|
|
||||||
def read_string_cast(self, type_=None) -> str:
|
def read_string_cast(self, type_: SignatureType) -> str:
|
||||||
"""Read a string using cast."""
|
"""Read a string using cast."""
|
||||||
self._pos += UINT32_SIZE + (-self._pos & (UINT32_SIZE - 1)) # align
|
self._pos += UINT32_SIZE + (-self._pos & (UINT32_SIZE - 1)) # align
|
||||||
str_start = self._pos
|
str_start = self._pos
|
||||||
@@ -252,7 +252,7 @@ class Unmarshaller:
|
|||||||
self._pos += self._view[start_pos : self._pos].cast(UINT32_CAST)[0] + 1
|
self._pos += self._view[start_pos : self._pos].cast(UINT32_CAST)[0] + 1
|
||||||
return self._buf[str_start : self._pos - 1].decode()
|
return self._buf[str_start : self._pos - 1].decode()
|
||||||
|
|
||||||
def read_string_unpack(self, type_=None) -> str:
|
def read_string_unpack(self, type_: SignatureType) -> str:
|
||||||
"""Read a string using unpack."""
|
"""Read a string using unpack."""
|
||||||
self._pos += UINT32_SIZE + (-self._pos & (UINT32_SIZE - 1)) # align
|
self._pos += UINT32_SIZE + (-self._pos & (UINT32_SIZE - 1)) # align
|
||||||
str_start = self._pos
|
str_start = self._pos
|
||||||
@@ -260,21 +260,21 @@ class Unmarshaller:
|
|||||||
self._pos += self._uint32_unpack(self._view, str_start - UINT32_SIZE)[0] + 1
|
self._pos += self._uint32_unpack(self._view, str_start - UINT32_SIZE)[0] + 1
|
||||||
return self._buf[str_start : self._pos - 1].decode()
|
return self._buf[str_start : self._pos - 1].decode()
|
||||||
|
|
||||||
def read_signature(self, type_=None) -> str:
|
def read_signature(self, type_: SignatureType) -> str:
|
||||||
signature_len = self._view[self._pos] # byte
|
signature_len = self._view[self._pos] # byte
|
||||||
o = self._pos + 1
|
o = self._pos + 1
|
||||||
# read terminating '\0' byte as well (str_length + 1)
|
# read terminating '\0' byte as well (str_length + 1)
|
||||||
self._pos = o + signature_len + 1
|
self._pos = o + signature_len + 1
|
||||||
return self._buf[o : o + signature_len].decode()
|
return self._buf[o : o + signature_len].decode()
|
||||||
|
|
||||||
def read_variant(self, type_=None) -> Variant:
|
def read_variant(self, type_: SignatureType) -> Variant:
|
||||||
tree = SignatureTree._get(self.read_signature())
|
tree = get_signature_tree(self.read_signature(type_))
|
||||||
# verify in Variant is only useful on construction not unmarshalling
|
# verify in Variant is only useful on construction not unmarshalling
|
||||||
return Variant(
|
return Variant(
|
||||||
tree, self._readers[tree.types[0].token](self, tree.types[0]), verify=False
|
tree, self._readers[tree.types[0].token](self, tree.types[0]), verify=False
|
||||||
)
|
)
|
||||||
|
|
||||||
def read_struct(self, type_=None) -> 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 [
|
||||||
@@ -344,7 +344,7 @@ class Unmarshaller:
|
|||||||
signature_len = self._view[self._pos] # byte
|
signature_len = self._view[self._pos] # byte
|
||||||
o = self._pos + 1
|
o = self._pos + 1
|
||||||
self._pos += signature_len + 2 # one for the byte, one for the '\0'
|
self._pos += signature_len + 2 # one for the byte, one for the '\0'
|
||||||
tree = SignatureTree._get(self._buf[o : o + signature_len].decode())
|
tree = get_signature_tree(self._buf[o : o + signature_len].decode())
|
||||||
headers[HEADER_NAME_MAP[field_0]] = self._readers[tree.types[0].token](
|
headers[HEADER_NAME_MAP[field_0]] = self._readers[tree.types[0].token](
|
||||||
self, tree.types[0]
|
self, tree.types[0]
|
||||||
)
|
)
|
||||||
@@ -391,7 +391,7 @@ class Unmarshaller:
|
|||||||
self._pos = HEADER_ARRAY_OF_STRUCT_SIGNATURE_POSITION
|
self._pos = HEADER_ARRAY_OF_STRUCT_SIGNATURE_POSITION
|
||||||
header_fields = self.header_fields(self._header_len)
|
header_fields = self.header_fields(self._header_len)
|
||||||
self._pos += -self._pos & 7 # align 8
|
self._pos += -self._pos & 7 # align 8
|
||||||
tree = SignatureTree._get(header_fields.get(HeaderField.SIGNATURE.name, ""))
|
tree = get_signature_tree(header_fields.get(HeaderField.SIGNATURE.name, ""))
|
||||||
self._message = Message(
|
self._message = Message(
|
||||||
destination=header_fields.get(HEADER_DESTINATION),
|
destination=header_fields.get(HEADER_DESTINATION),
|
||||||
path=header_fields.get(HEADER_PATH),
|
path=header_fields.get(HEADER_PATH),
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import ast
|
|||||||
import inspect
|
import inspect
|
||||||
from typing import Any, List, Union
|
from typing import Any, List, Union
|
||||||
|
|
||||||
from ..signature import SignatureTree, Variant
|
from ..signature import SignatureTree, Variant, get_signature_tree
|
||||||
|
|
||||||
|
|
||||||
def signature_contains_type(
|
def signature_contains_type(
|
||||||
@@ -11,7 +11,7 @@ def signature_contains_type(
|
|||||||
"""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"""
|
||||||
if type(signature) is str:
|
if type(signature) is str:
|
||||||
signature = SignatureTree._get(signature)
|
signature = get_signature_tree(signature)
|
||||||
|
|
||||||
queue = []
|
queue = []
|
||||||
contains_variants = False
|
contains_variants = False
|
||||||
@@ -56,7 +56,7 @@ def replace_fds_with_idx(
|
|||||||
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
|
||||||
the Message"""
|
the Message"""
|
||||||
if type(signature) is str:
|
if type(signature) is str:
|
||||||
signature = SignatureTree._get(signature)
|
signature = get_signature_tree(signature)
|
||||||
|
|
||||||
if not signature_contains_type(signature, body, "h"):
|
if not signature_contains_type(signature, body, "h"):
|
||||||
return body, []
|
return body, []
|
||||||
@@ -82,7 +82,7 @@ def replace_idx_with_fds(
|
|||||||
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."""
|
||||||
if type(signature) is str:
|
if type(signature) is str:
|
||||||
signature = SignatureTree._get(signature)
|
signature = get_signature_tree(signature)
|
||||||
|
|
||||||
if not signature_contains_type(signature, body, "h"):
|
if not signature_contains_type(signature, body, "h"):
|
||||||
return body
|
return body
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from typing import List, Union
|
|||||||
|
|
||||||
from .constants import ArgDirection, PropertyAccess
|
from .constants import ArgDirection, PropertyAccess
|
||||||
from .errors import InvalidIntrospectionError
|
from .errors import InvalidIntrospectionError
|
||||||
from .signature import SignatureTree, SignatureType
|
from .signature import SignatureType, get_signature_tree
|
||||||
from .validators import assert_interface_name_valid, assert_member_name_valid
|
from .validators import assert_interface_name_valid, assert_member_name_valid
|
||||||
|
|
||||||
# https://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format
|
# https://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format
|
||||||
@@ -42,7 +42,7 @@ class Arg:
|
|||||||
type_ = signature
|
type_ = signature
|
||||||
signature = signature.signature
|
signature = signature.signature
|
||||||
else:
|
else:
|
||||||
tree = SignatureTree._get(signature)
|
tree = get_signature_tree(signature)
|
||||||
if len(tree.types) != 1:
|
if len(tree.types) != 1:
|
||||||
raise InvalidIntrospectionError(
|
raise InvalidIntrospectionError(
|
||||||
f"an argument must have a single complete type. (has {len(tree.types)} types)"
|
f"an argument must have a single complete type. (has {len(tree.types)} types)"
|
||||||
@@ -248,7 +248,7 @@ class Property:
|
|||||||
):
|
):
|
||||||
assert_member_name_valid(name)
|
assert_member_name_valid(name)
|
||||||
|
|
||||||
tree = SignatureTree._get(signature)
|
tree = get_signature_tree(signature)
|
||||||
if len(tree.types) != 1:
|
if len(tree.types) != 1:
|
||||||
raise InvalidIntrospectionError(
|
raise InvalidIntrospectionError(
|
||||||
f"properties must have a single complete type. (has {len(tree.types)} types)"
|
f"properties must have a single complete type. (has {len(tree.types)} types)"
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from ._private.constants import LITTLE_ENDIAN, PROTOCOL_VERSION, HeaderField
|
|||||||
from ._private.marshaller import Marshaller
|
from ._private.marshaller import Marshaller
|
||||||
from .constants import ErrorType, MessageFlag, MessageType
|
from .constants import ErrorType, MessageFlag, MessageType
|
||||||
from .errors import InvalidMessageError
|
from .errors import InvalidMessageError
|
||||||
from .signature import SignatureTree, Variant
|
from .signature import SignatureTree, Variant, get_signature_tree
|
||||||
from .validators import (
|
from .validators import (
|
||||||
assert_bus_name_valid,
|
assert_bus_name_valid,
|
||||||
assert_interface_name_valid,
|
assert_interface_name_valid,
|
||||||
@@ -129,7 +129,7 @@ class Message:
|
|||||||
self.signature_tree = signature
|
self.signature_tree = signature
|
||||||
else:
|
else:
|
||||||
self.signature = signature
|
self.signature = signature
|
||||||
self.signature_tree = SignatureTree._get(signature)
|
self.signature_tree = get_signature_tree(signature)
|
||||||
self.body = body
|
self.body = body
|
||||||
self.serial = serial
|
self.serial = serial
|
||||||
|
|
||||||
@@ -255,13 +255,6 @@ class Message:
|
|||||||
unix_fds=unix_fds,
|
unix_fds=unix_fds,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _matches(self, **kwargs):
|
|
||||||
for attr, val in kwargs.items():
|
|
||||||
if getattr(self, attr) != val:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def _marshall(self, negotiate_unix_fd=False):
|
def _marshall(self, negotiate_unix_fd=False):
|
||||||
# TODO maximum message size is 134217728 (128 MiB)
|
# TODO maximum message size is 134217728 (128 MiB)
|
||||||
body_block = Marshaller(self.signature, self.body)
|
body_block = Marshaller(self.signature, self.body)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ from ._private.util import (
|
|||||||
)
|
)
|
||||||
from .constants import PropertyAccess
|
from .constants import PropertyAccess
|
||||||
from .errors import SignalDisabledError
|
from .errors import SignalDisabledError
|
||||||
from .signature import SignatureBodyMismatchError, SignatureTree, Variant
|
from .signature import SignatureBodyMismatchError, Variant, get_signature_tree
|
||||||
|
|
||||||
|
|
||||||
class _Method:
|
class _Method:
|
||||||
@@ -39,7 +39,7 @@ class _Method:
|
|||||||
out_args = []
|
out_args = []
|
||||||
out_signature = parse_annotation(inspection.return_annotation)
|
out_signature = parse_annotation(inspection.return_annotation)
|
||||||
if out_signature:
|
if out_signature:
|
||||||
for type_ in SignatureTree._get(out_signature).types:
|
for type_ in get_signature_tree(out_signature).types:
|
||||||
out_args.append(intr.Arg(type_, intr.ArgDirection.OUT))
|
out_args.append(intr.Arg(type_, intr.ArgDirection.OUT))
|
||||||
|
|
||||||
self.name = name
|
self.name = name
|
||||||
@@ -48,8 +48,8 @@ class _Method:
|
|||||||
self.introspection = intr.Method(name, in_args, out_args)
|
self.introspection = intr.Method(name, in_args, out_args)
|
||||||
self.in_signature = in_signature
|
self.in_signature = in_signature
|
||||||
self.out_signature = out_signature
|
self.out_signature = out_signature
|
||||||
self.in_signature_tree = SignatureTree._get(in_signature)
|
self.in_signature_tree = get_signature_tree(in_signature)
|
||||||
self.out_signature_tree = SignatureTree._get(out_signature)
|
self.out_signature_tree = get_signature_tree(out_signature)
|
||||||
|
|
||||||
|
|
||||||
def method(name: str = None, disabled: bool = False):
|
def method(name: str = None, disabled: bool = False):
|
||||||
@@ -116,12 +116,12 @@ class _Signal:
|
|||||||
|
|
||||||
if return_annotation:
|
if return_annotation:
|
||||||
signature = return_annotation
|
signature = return_annotation
|
||||||
signature_tree = SignatureTree._get(signature)
|
signature_tree = get_signature_tree(signature)
|
||||||
for type_ in signature_tree.types:
|
for type_ in signature_tree.types:
|
||||||
args.append(intr.Arg(type_, intr.ArgDirection.OUT))
|
args.append(intr.Arg(type_, intr.ArgDirection.OUT))
|
||||||
else:
|
else:
|
||||||
signature = ""
|
signature = ""
|
||||||
signature_tree = SignatureTree._get("")
|
signature_tree = get_signature_tree("")
|
||||||
|
|
||||||
self.signature = signature
|
self.signature = signature
|
||||||
self.signature_tree = signature_tree
|
self.signature_tree = signature_tree
|
||||||
@@ -226,7 +226,7 @@ class _Property(property):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.signature = return_annotation
|
self.signature = return_annotation
|
||||||
tree = SignatureTree._get(return_annotation)
|
tree = get_signature_tree(return_annotation)
|
||||||
|
|
||||||
if len(tree.types) != 1:
|
if len(tree.types) != 1:
|
||||||
raise ValueError("the property signature must be a single complete type")
|
raise ValueError("the property signature must be a single complete type")
|
||||||
|
|||||||
16
src/dbus_fast/signature.pxd
Normal file
16
src/dbus_fast/signature.pxd
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
"""cdefs for signature.py"""
|
||||||
|
|
||||||
|
import cython
|
||||||
|
|
||||||
|
|
||||||
|
cdef class SignatureType:
|
||||||
|
|
||||||
|
cdef public str token
|
||||||
|
cdef public list children
|
||||||
|
cdef str _signature
|
||||||
|
|
||||||
|
|
||||||
|
cdef class SignatureTree:
|
||||||
|
|
||||||
|
cdef public str signature
|
||||||
|
cdef public list types
|
||||||
@@ -330,10 +330,7 @@ class SignatureTree:
|
|||||||
:class:`InvalidSignatureError` if the given signature is not valid.
|
:class:`InvalidSignatureError` if the given signature is not valid.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@staticmethod
|
__slots__ = ("signature", "types")
|
||||||
@lru_cache(maxsize=None)
|
|
||||||
def _get(signature: str = "") -> "SignatureTree":
|
|
||||||
return SignatureTree(signature)
|
|
||||||
|
|
||||||
def __init__(self, signature: str = ""):
|
def __init__(self, signature: str = ""):
|
||||||
self.signature = signature
|
self.signature = signature
|
||||||
@@ -414,7 +411,7 @@ class Variant:
|
|||||||
signature_str = signature.signature
|
signature_str = signature.signature
|
||||||
signature_tree = None
|
signature_tree = None
|
||||||
elif type(signature) is str:
|
elif type(signature) is str:
|
||||||
signature_tree = SignatureTree._get(signature)
|
signature_tree = get_signature_tree(signature)
|
||||||
else:
|
else:
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
"signature must be a SignatureTree, SignatureType, or a string"
|
"signature must be a SignatureTree, SignatureType, or a string"
|
||||||
@@ -445,3 +442,8 @@ class Variant:
|
|||||||
return "<dbus_fast.signature.Variant ('{}', {})>".format(
|
return "<dbus_fast.signature.Variant ('{}', {})>".format(
|
||||||
self.type.signature, self.value
|
self.type.signature, self.value
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache(maxsize=None)
|
||||||
|
def get_signature_tree(signature: str = "") -> SignatureTree:
|
||||||
|
return SignatureTree(signature)
|
||||||
|
|||||||
Reference in New Issue
Block a user