4
4
import greenlet
5
5
import pytest
6
6
7
- from twisted .internet import defer , reactor
7
+ from twisted .internet import error , defer , reactor
8
8
from twisted .internet .threads import blockingCallFromThread
9
9
from twisted .python import failure
10
10
@@ -39,6 +39,7 @@ def block_from_thread(d):
39
39
40
40
@decorator .decorator
41
41
def inlineCallbacks (fun , * args , ** kw ):
42
+ print ('checkpoint' , 'pytest-twisted' , 'inlineCallbacks' )
42
43
return defer .inlineCallbacks (fun )(* args , ** kw )
43
44
44
45
@@ -53,40 +54,75 @@ def stop_twisted_greenlet():
53
54
gr_twisted .switch ()
54
55
55
56
56
- @pytest .hookimpl (trylast = True )
57
- def pytest_configure (config ):
57
+ def create_twisted_greenlet ():
58
58
global gr_twisted
59
- global reactor
60
-
61
59
if not gr_twisted and not reactor .running :
62
- if config .getoption ('qt5reactor' ):
63
- if 'twisted.internet.reactor' in sys .modules :
64
- del sys .modules ['twisted.internet.reactor' ]
65
-
66
- import qt5reactor
67
- qt5reactor .install ()
68
-
69
- import twisted .internet .reactor
70
- reactor = twisted .internet .reactor
71
-
72
60
gr_twisted = greenlet .greenlet (reactor .run )
73
61
# give me better tracebacks:
74
62
failure .Failure .cleanFailure = lambda self : None
75
63
76
64
65
+ def pytest_addhooks (pluginmanager ):
66
+ create_twisted_greenlet ()
67
+
68
+
77
69
def pytest_addoption (parser ):
78
70
group = parser .getgroup ('twisted' )
79
71
group .addoption ('--qt5reactor' , dest = 'qt5reactor' , action = 'store_true' ,
80
72
help = 'prepare for use with qt5reactor' )
81
73
82
74
75
+ def pytest_configure (config ):
76
+ # TODO: why is the parameter needed?
77
+ def default_reactor (_ ):
78
+ print ('checkpoint' , 'pytest-twisted' , 'reactor (default)' )
79
+ global reactor
80
+ from twisted .internet import reactor
81
+ create_twisted_greenlet ()
82
+
83
+ def qt5_reactor (qapp ):
84
+ print ('checkpoint' , 'pytest-twisted' , 'reactor (qt5)' )
85
+ global gr_twisted
86
+ global reactor
87
+ import qt5reactor
88
+
89
+ try :
90
+ qt5reactor .install ()
91
+ except error .ReactorAlreadyInstalledError :
92
+ if not isinstance (reactor , qt5reactor .QtReactor ):
93
+ stop_twisted_greenlet ()
94
+ gr_twisted = None
95
+ del sys .modules ['twisted.internet.reactor' ]
96
+ qt5reactor .install ()
97
+ print ('checkpoint' , 'pytest-twisted' , 'qt5reactor installed' )
98
+ from twisted .internet import reactor
99
+
100
+ create_twisted_greenlet ()
101
+ else :
102
+ create_twisted_greenlet ()
103
+
104
+ if config .getoption ('qt5reactor' ):
105
+ reactor_fixture = qt5_reactor
106
+ else :
107
+ reactor_fixture = default_reactor
108
+
109
+ class ReactorPlugin (object ):
110
+ reactor = (
111
+ pytest .fixture (scope = 'session' , autouse = True )(reactor_fixture )
112
+ )
113
+
114
+ config .pluginmanager .register (ReactorPlugin ())
115
+
116
+
83
117
@pytest .fixture (scope = "session" , autouse = True )
84
- def twisted_greenlet (request ):
118
+ def twisted_greenlet (request , reactor ):
119
+ print ('checkpoint' , 'pytest-twisted' , 'twisted_greenlet' )
85
120
request .addfinalizer (stop_twisted_greenlet )
86
121
return gr_twisted
87
122
88
123
89
124
def _pytest_pyfunc_call (pyfuncitem ):
125
+ print ('checkpoint' , 'pytest-twisted' , '_pytest_pyfunc_call' )
90
126
testfunction = pyfuncitem .obj
91
127
if pyfuncitem ._isyieldedfunction ():
92
128
return testfunction (* pyfuncitem ._args )
@@ -102,6 +138,7 @@ def _pytest_pyfunc_call(pyfuncitem):
102
138
103
139
104
140
def pytest_pyfunc_call (pyfuncitem ):
141
+ print ('checkpoint' , 'pytest-twisted' , 'pytest_pyfunc_call' )
105
142
if gr_twisted is not None :
106
143
if gr_twisted .dead :
107
144
raise RuntimeError ("twisted reactor has stopped" )
0 commit comments