66
77from functools import wraps
88import inspect
9- from typing import no_type_check_decorator , Dict , List , Any
9+ from typing import no_type_check_decorator , Dict , List , Any , Optional
1010import copy
1111import asyncio
1212
1313
1414class _Method :
15- def __init__ (self , fn , name , disabled = False ):
16- in_signature = ''
17- out_signature = ''
15+ def __init__ (self , fn , name , disabled = False , in_signature : Optional [str ] = None , out_signature : Optional [str ] = None ):
1816
1917 inspection = inspect .signature (fn )
2018
21- in_args = []
22- for i , param in enumerate (inspection .parameters .values ()):
23- if i == 0 :
24- # first is self
25- continue
26- annotation = parse_annotation (param .annotation )
27- if not annotation :
28- raise ValueError (
29- 'method parameters must specify the dbus type string as an annotation' )
30- in_args .append (intr .Arg (annotation , intr .ArgDirection .IN , param .name ))
31- in_signature += annotation
19+ if in_signature is None :
20+ in_signature = ''
21+ in_args = []
22+ for i , param in enumerate (inspection .parameters .values ()):
23+ if i == 0 :
24+ # first is self
25+ continue
26+ annotation = parse_annotation (param .annotation )
27+ if not annotation :
28+ raise ValueError (
29+ 'method parameters must specify the dbus type string as an annotation' )
30+ in_args .append (intr .Arg (annotation , intr .ArgDirection .IN , param .name ))
31+ in_signature += annotation
32+ else :
33+ name_iter = iter (inspection .parameters .keys ())
34+ next (name_iter ) # skip self parameter
35+ in_args = [intr .Arg (type_ , intr .ArgDirection .IN , name ) for
36+ name , type_ in zip (name_iter , SignatureTree ._get (in_signature ).types )]
37+
38+ if out_signature is None :
39+ out_signature = parse_annotation (inspection .return_annotation )
3240
3341 out_args = []
34- out_signature = parse_annotation (inspection .return_annotation )
3542 if out_signature :
3643 for type_ in SignatureTree ._get (out_signature ).types :
3744 out_args .append (intr .Arg (type_ , intr .ArgDirection .OUT ))
@@ -41,12 +48,12 @@ def __init__(self, fn, name, disabled=False):
4148 self .disabled = disabled
4249 self .introspection = intr .Method (name , in_args , out_args )
4350 self .in_signature = in_signature
44- self .out_signature = out_signature
4551 self .in_signature_tree = SignatureTree ._get (in_signature )
52+ self .out_signature = out_signature
4653 self .out_signature_tree = SignatureTree ._get (out_signature )
4754
4855
49- def method (name : str = None , disabled : bool = False ):
56+ def method (name : str = None , disabled : bool = False , in_signature : Optional [ str ] = None , out_signature : Optional [ str ] = None ):
5057 """A decorator to mark a class method of a :class:`ServiceInterface` to be a DBus service method.
5158
5259 The parameters and return value must each be annotated with a signature
@@ -91,7 +98,8 @@ def wrapped(*args, **kwargs):
9198 fn (* args , ** kwargs )
9299
93100 fn_name = name if name else fn .__name__
94- wrapped .__dict__ ['__DBUS_METHOD' ] = _Method (fn , fn_name , disabled = disabled )
101+ _method = _Method (fn , fn_name , disabled = disabled , in_signature = in_signature , out_signature = out_signature )
102+ wrapped .__dict__ ['__DBUS_METHOD' ] = _method
95103
96104 return wrapped
97105
0 commit comments