8
8
from twisted .internet .threads import blockingCallFromThread
9
9
from twisted .python import failure
10
10
11
- gr_twisted = None
12
- reactor = None
11
+
12
+ class _instances :
13
+ gr_twisted = None
14
+ reactor = None
15
+
16
+
17
+ def pytest_namespace ():
18
+ return dict (inlineCallbacks = inlineCallbacks , blockon = blockon )
13
19
14
20
15
21
def blockon (d ):
16
- if reactor .running :
22
+ if _instances . reactor .running :
17
23
return block_from_thread (d )
18
24
19
25
return blockon_default (d )
20
26
21
27
22
28
def blockon_default (d ):
23
29
current = greenlet .getcurrent ()
24
- assert current is not gr_twisted , \
25
- " blockon cannot be called from the twisted greenlet"
30
+ assert current is not _instances . gr_twisted , \
31
+ ' blockon cannot be called from the twisted greenlet'
26
32
result = []
27
33
28
34
def cb (r ):
@@ -32,8 +38,8 @@ def cb(r):
32
38
33
39
d .addCallbacks (cb , cb )
34
40
if not result :
35
- _result = gr_twisted .switch ()
36
- assert _result is result , " illegal switch in blockon"
41
+ _result = _instances . gr_twisted .switch ()
42
+ assert _result is result , ' illegal switch in blockon'
37
43
38
44
if isinstance (result [0 ], failure .Failure ):
39
45
result [0 ].raiseException ()
@@ -42,96 +48,28 @@ def cb(r):
42
48
43
49
44
50
def block_from_thread (d ):
45
- return blockingCallFromThread (reactor , lambda x : x , d )
51
+ return blockingCallFromThread (_instances . reactor , lambda x : x , d )
46
52
47
53
48
54
@decorator .decorator
49
55
def inlineCallbacks (fun , * args , ** kw ):
50
56
return defer .inlineCallbacks (fun )(* args , ** kw )
51
57
52
58
53
- def pytest_namespace ():
54
- return dict (inlineCallbacks = inlineCallbacks ,
55
- blockon = blockon )
56
-
57
-
58
- def stop_twisted_greenlet ():
59
- if gr_twisted :
60
- reactor .stop ()
61
- gr_twisted .switch ()
62
-
63
-
64
- def create_twisted_greenlet ():
65
- global gr_twisted
66
- if reactor is None :
59
+ def init_twisted_greenlet ():
60
+ if _instances .reactor is None :
67
61
return
68
62
69
- if not gr_twisted and not reactor .running :
70
- gr_twisted = greenlet .greenlet (reactor .run )
63
+ if not _instances . gr_twisted and not _instances . reactor .running :
64
+ _instances . gr_twisted = greenlet .greenlet (_instances . reactor .run )
71
65
# give me better tracebacks:
72
66
failure .Failure .cleanFailure = lambda self : None
73
67
74
68
75
- def pytest_addhooks (pluginmanager ):
76
- create_twisted_greenlet ()
77
-
78
-
79
- def pytest_addoption (parser ):
80
- group = parser .getgroup ('twisted' )
81
- group .addoption ('--qt5reactor' , dest = 'qt5reactor' , action = 'store_true' ,
82
- help = 'prepare for use with qt5reactor' )
83
-
84
-
85
- def pytest_configure (config ):
86
- # TODO: why is the parameter needed?
87
- def default_reactor ():
88
- global reactor
89
- import twisted .internet .reactor
90
- reactor = twisted .internet .reactor
91
- create_twisted_greenlet ()
92
-
93
- def qt5_reactor (qapp ):
94
- global gr_twisted
95
- global reactor
96
- import qt5reactor
97
-
98
- reinstalled = False
99
-
100
- try :
101
- qt5reactor .install ()
102
- except error .ReactorAlreadyInstalledError :
103
- if not isinstance (reactor , qt5reactor .QtReactor ):
104
- stop_twisted_greenlet ()
105
- gr_twisted = None
106
- del sys .modules ['twisted.internet.reactor' ]
107
- qt5reactor .install ()
108
- reinstalled = True
109
- else :
110
- reinstalled = True
111
-
112
- if reinstalled :
113
- import twisted .internet .reactor
114
- reactor = twisted .internet .reactor
115
-
116
- create_twisted_greenlet ()
117
-
118
- if config .getoption ('qt5reactor' ):
119
- reactor_fixture = qt5_reactor
120
- else :
121
- reactor_fixture = default_reactor
122
-
123
- class ReactorPlugin (object ):
124
- reactor = staticmethod (
125
- pytest .fixture (scope = 'session' , autouse = True )(reactor_fixture )
126
- )
127
-
128
- config .pluginmanager .register (ReactorPlugin ())
129
-
130
-
131
- @pytest .fixture (scope = "session" , autouse = True )
132
- def twisted_greenlet (request , reactor ):
133
- request .addfinalizer (stop_twisted_greenlet )
134
- return gr_twisted
69
+ def stop_twisted_greenlet ():
70
+ if _instances .gr_twisted :
71
+ _instances .reactor .stop ()
72
+ _instances .gr_twisted .switch ()
135
73
136
74
137
75
def _pytest_pyfunc_call (pyfuncitem ):
@@ -140,7 +78,7 @@ def _pytest_pyfunc_call(pyfuncitem):
140
78
return testfunction (* pyfuncitem ._args )
141
79
else :
142
80
funcargs = pyfuncitem .funcargs
143
- if hasattr (pyfuncitem , " _fixtureinfo" ):
81
+ if hasattr (pyfuncitem , ' _fixtureinfo' ):
144
82
testargs = {}
145
83
for arg in pyfuncitem ._fixtureinfo .argnames :
146
84
testargs [arg ] = funcargs [arg ]
@@ -150,18 +88,66 @@ def _pytest_pyfunc_call(pyfuncitem):
150
88
151
89
152
90
def pytest_pyfunc_call (pyfuncitem ):
153
- if gr_twisted is not None :
154
- if gr_twisted .dead :
155
- raise RuntimeError (" twisted reactor has stopped" )
91
+ if _instances . gr_twisted is not None :
92
+ if _instances . gr_twisted .dead :
93
+ raise RuntimeError (' twisted reactor has stopped' )
156
94
157
95
def in_reactor (d , f , * args ):
158
96
return defer .maybeDeferred (f , * args ).chainDeferred (d )
159
97
160
98
d = defer .Deferred ()
161
- reactor .callLater (0.0 , in_reactor , d , _pytest_pyfunc_call , pyfuncitem )
99
+ _instances .reactor .callLater (
100
+ 0.0 , in_reactor , d , _pytest_pyfunc_call , pyfuncitem
101
+ )
162
102
blockon_default (d )
163
103
else :
164
- if not reactor .running :
165
- raise RuntimeError ("twisted reactor is not running" )
166
- blockingCallFromThread (reactor , _pytest_pyfunc_call , pyfuncitem )
104
+ if not _instances .reactor .running :
105
+ raise RuntimeError ('twisted reactor is not running' )
106
+ blockingCallFromThread (
107
+ _instances .reactor , _pytest_pyfunc_call , pyfuncitem
108
+ )
167
109
return True
110
+
111
+
112
+ @pytest .fixture (scope = "session" , autouse = True )
113
+ def twisted_greenlet (request , reactor ):
114
+ request .addfinalizer (stop_twisted_greenlet )
115
+ return _instances .gr_twisted
116
+
117
+
118
+ def init_reactor ():
119
+ import twisted .internet .reactor
120
+ _instances .reactor = twisted .internet .reactor
121
+ init_twisted_greenlet ()
122
+
123
+
124
+ def init_qt5_reactor (qapp ):
125
+ import qt5reactor
126
+ try :
127
+ qt5reactor .install ()
128
+ except error .ReactorAlreadyInstalledError :
129
+ if not isinstance (_instances .reactor , qt5reactor .QtReactor ):
130
+ stop_twisted_greenlet ()
131
+ _instances .gr_twisted = None
132
+ del sys .modules ['twisted.internet.reactor' ]
133
+ qt5reactor .install ()
134
+ init_reactor ()
135
+
136
+
137
+ def pytest_addoption (parser ):
138
+ group = parser .getgroup ('twisted' )
139
+ group .addoption ('--qt5reactor' , dest = 'qt5reactor' , action = 'store_true' ,
140
+ help = 'prepare for use with qt5reactor' )
141
+
142
+
143
+ def pytest_configure (config ):
144
+ reactor_fixture = init_reactor
145
+ if config .getoption ('qt5reactor' ):
146
+ reactor_fixture = init_qt5_reactor
147
+
148
+ class ReactorPlugin (object ):
149
+ reactor = staticmethod (
150
+ pytest .fixture (scope = 'session' , autouse = True )(reactor_fixture )
151
+ )
152
+
153
+ config .pluginmanager .register (ReactorPlugin ())
0 commit comments