-
Notifications
You must be signed in to change notification settings - Fork 61
Expand file tree
/
Copy pathtest_decorators_annotated.py
More file actions
162 lines (127 loc) · 5.47 KB
/
test_decorators_annotated.py
File metadata and controls
162 lines (127 loc) · 5.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
from typing import List
from dbus_next import PropertyAccess, introspection as intr
from dbus_next.service import method, signal, dbus_property, ServiceInterface
from test.util import check_annotated, skip_reason_no_typing_annotated
import pytest
has_annotated = check_annotated()
if has_annotated:
from test.util import Annotated
class ExampleInterface(ServiceInterface):
def __init__(self):
super().__init__('test.interface')
self._some_prop = 55
self._another_prop = 101
self._weird_prop = 500
@method()
def some_method(self, one: Annotated[str, 's'], two: Annotated[str,
's']) -> Annotated[str, 's']:
return 'hello'
@method(name='renamed_method', disabled=True)
def another_method(self, eight: Annotated[str, 'o'], six: Annotated[str, 't']):
pass
@signal()
def some_signal(self) -> Annotated[List[str], 'as']:
return ['result']
@signal(name='renamed_signal', disabled=True)
def another_signal(self) -> Annotated[List, '(dodo)']:
return [1, '/', 1, '/']
# an additional annotation is added to this one. PEP 593 says we shoould be
# able to deal with that and only select the annotation that we understand
@dbus_property(name='renamed_readonly_property', access=PropertyAccess.READ, disabled=True)
def another_prop(self) -> Annotated[int, 42, 't']:
return self._another_prop
@dbus_property()
def some_prop(self) -> Annotated[int, 'u']:
return self._some_prop
@some_prop.setter
def some_prop(self, val: Annotated[int, 'u']):
self._some_prop = val + 1
# for this one, the setter has a different name than the getter which is a
# special case in the code
@dbus_property()
def weird_prop(self) -> Annotated[int, 't']:
return self._weird_prop
@weird_prop.setter
def setter_for_weird_prop(self, val: Annotated[int, 't']):
self._weird_prop = val
@pytest.mark.skipif(not has_annotated, reason=skip_reason_no_typing_annotated)
def test_method_decorator():
interface = ExampleInterface()
assert interface.name == 'test.interface'
properties = ServiceInterface._get_properties(interface)
methods = ServiceInterface._get_methods(interface)
signals = ServiceInterface._get_signals(interface)
assert len(methods) == 2
method = methods[0]
assert method.name == 'renamed_method'
assert method.in_signature == 'ot'
assert method.out_signature == ''
assert method.disabled
assert type(method.introspection) is intr.Method
method = methods[1]
assert method.name == 'some_method'
assert method.in_signature == 'ss'
assert method.out_signature == 's'
assert not method.disabled
assert type(method.introspection) is intr.Method
assert len(signals) == 2
signal = signals[0]
assert signal.name == 'renamed_signal'
assert signal.signature == '(dodo)'
assert signal.disabled
assert type(signal.introspection) is intr.Signal
signal = signals[1]
assert signal.name == 'some_signal'
assert signal.signature == 'as'
assert not signal.disabled
assert type(signal.introspection) is intr.Signal
assert len(properties) == 3
renamed_readonly_prop = properties[0]
assert renamed_readonly_prop.name == 'renamed_readonly_property'
assert renamed_readonly_prop.signature == 't'
assert renamed_readonly_prop.access == PropertyAccess.READ
assert renamed_readonly_prop.disabled
assert type(renamed_readonly_prop.introspection) is intr.Property
weird_prop = properties[1]
assert weird_prop.name == 'weird_prop'
assert weird_prop.access == PropertyAccess.READWRITE
assert weird_prop.signature == 't'
assert not weird_prop.disabled
assert weird_prop.prop_getter is not None
assert weird_prop.prop_getter.__name__ == 'weird_prop'
assert weird_prop.prop_setter is not None
assert weird_prop.prop_setter.__name__ == 'setter_for_weird_prop'
assert type(weird_prop.introspection) is intr.Property
prop = properties[2]
assert prop.name == 'some_prop'
assert prop.access == PropertyAccess.READWRITE
assert prop.signature == 'u'
assert not prop.disabled
assert prop.prop_getter is not None
assert prop.prop_setter is not None
assert type(prop.introspection) is intr.Property
# make sure the getter and setter actually work
assert interface._some_prop == 55
interface._some_prop = 555
assert interface.some_prop == 555
assert interface._weird_prop == 500
assert weird_prop.prop_getter(interface) == 500
interface._weird_prop = 1001
assert interface._weird_prop == 1001
weird_prop.prop_setter(interface, 600)
assert interface._weird_prop == 600
@pytest.mark.skipif(not has_annotated, reason=skip_reason_no_typing_annotated)
def test_interface_introspection():
interface = ExampleInterface()
intr_interface = interface.introspect()
assert type(intr_interface) is intr.Interface
xml = intr_interface.to_xml()
assert xml.tag == 'interface'
assert xml.attrib.get('name', None) == 'test.interface'
methods = xml.findall('method')
signals = xml.findall('signal')
properties = xml.findall('property')
assert len(xml) == 4
assert len(methods) == 1
assert len(signals) == 1
assert len(properties) == 2