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 ,
16+ fn ,
17+ name ,
18+ disabled = False ,
19+ in_signature : Optional [str ] = None ,
20+ out_signature : Optional [str ] = None ):
1821
1922 inspection = inspect .signature (fn )
2023
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
24+ if in_signature is None :
25+ in_signature = ''
26+ in_args = []
27+ for i , param in enumerate (inspection .parameters .values ()):
28+ if i == 0 :
29+ # first is self
30+ continue
31+ annotation = parse_annotation (param .annotation )
32+ if not annotation :
33+ raise ValueError (
34+ 'method parameters must specify the dbus type string as an annotation' )
35+ in_args .append (intr .Arg (annotation , intr .ArgDirection .IN , param .name ))
36+ in_signature += annotation
37+ else :
38+ name_iter = iter (inspection .parameters .keys ())
39+ next (name_iter ) # skip self parameter
40+ in_args = [
41+ intr .Arg (type_ , intr .ArgDirection .IN , name )
42+ for name , type_ in zip (name_iter ,
43+ SignatureTree ._get (in_signature ).types )
44+ ]
45+
46+ if out_signature is None :
47+ out_signature = parse_annotation (inspection .return_annotation )
3248
3349 out_args = []
34- out_signature = parse_annotation (inspection .return_annotation )
3550 if out_signature :
3651 for type_ in SignatureTree ._get (out_signature ).types :
3752 out_args .append (intr .Arg (type_ , intr .ArgDirection .OUT ))
@@ -41,12 +56,15 @@ def __init__(self, fn, name, disabled=False):
4156 self .disabled = disabled
4257 self .introspection = intr .Method (name , in_args , out_args )
4358 self .in_signature = in_signature
44- self .out_signature = out_signature
4559 self .in_signature_tree = SignatureTree ._get (in_signature )
60+ self .out_signature = out_signature
4661 self .out_signature_tree = SignatureTree ._get (out_signature )
4762
4863
49- def method (name : str = None , disabled : bool = False ):
64+ def method (name : str = None ,
65+ disabled : bool = False ,
66+ in_signature : Optional [str ] = None ,
67+ out_signature : Optional [str ] = None ):
5068 """A decorator to mark a class method of a :class:`ServiceInterface` to be a DBus service method.
5169
5270 The parameters and return value must each be annotated with a signature
@@ -91,7 +109,12 @@ def wrapped(*args, **kwargs):
91109 fn (* args , ** kwargs )
92110
93111 fn_name = name if name else fn .__name__
94- wrapped .__dict__ ['__DBUS_METHOD' ] = _Method (fn , fn_name , disabled = disabled )
112+ _method = _Method (fn ,
113+ fn_name ,
114+ disabled = disabled ,
115+ in_signature = in_signature ,
116+ out_signature = out_signature )
117+ wrapped .__dict__ ['__DBUS_METHOD' ] = _method
95118
96119 return wrapped
97120
0 commit comments