@@ -72,6 +72,7 @@ def __init__(self, hookspecs=None):
72
72
self ._name2plugin = {}
73
73
self ._listattrcache = {}
74
74
self ._plugins = []
75
+ self ._conftestplugins = []
75
76
self ._warnings = []
76
77
self .trace = TagTracer ().get ("pluginmanage" )
77
78
self ._plugin_distinfo = []
@@ -86,7 +87,7 @@ def set_register_callback(self, callback):
86
87
assert not hasattr (self , "_registercallback" )
87
88
self ._registercallback = callback
88
89
89
- def register (self , plugin , name = None , prepend = False ):
90
+ def register (self , plugin , name = None , prepend = False , conftest = False ):
90
91
if self ._name2plugin .get (name , None ) == - 1 :
91
92
return
92
93
name = name or getattr (plugin , '__name__' , str (id (plugin )))
@@ -98,16 +99,22 @@ def register(self, plugin, name=None, prepend=False):
98
99
reg = getattr (self , "_registercallback" , None )
99
100
if reg is not None :
100
101
reg (plugin , name )
101
- if not prepend :
102
- self ._plugins .append (plugin )
102
+ if conftest :
103
+ self ._conftestplugins .append (plugin )
103
104
else :
104
- self ._plugins .insert (0 , plugin )
105
+ if not prepend :
106
+ self ._plugins .append (plugin )
107
+ else :
108
+ self ._plugins .insert (0 , plugin )
105
109
return True
106
110
107
111
def unregister (self , plugin = None , name = None ):
108
112
if plugin is None :
109
113
plugin = self .getplugin (name = name )
110
- self ._plugins .remove (plugin )
114
+ try :
115
+ self ._plugins .remove (plugin )
116
+ except KeyError :
117
+ self ._conftestplugins .remove (plugin )
111
118
for name , value in list (self ._name2plugin .items ()):
112
119
if value == plugin :
113
120
del self ._name2plugin [name ]
@@ -119,7 +126,7 @@ def ensure_shutdown(self):
119
126
while self ._shutdown :
120
127
func = self ._shutdown .pop ()
121
128
func ()
122
- self ._plugins = []
129
+ self ._plugins = self . _conftestplugins = []
123
130
self ._name2plugin .clear ()
124
131
self ._listattrcache .clear ()
125
132
@@ -134,7 +141,7 @@ def addhooks(self, spec, prefix="pytest_"):
134
141
self .hook ._addhooks (spec , prefix = prefix )
135
142
136
143
def getplugins (self ):
137
- return list ( self ._plugins )
144
+ return self ._plugins + self . _conftestplugins
138
145
139
146
def skipifmissing (self , name ):
140
147
if not self .hasplugin (name ):
@@ -198,7 +205,8 @@ def consider_pluginarg(self, arg):
198
205
self .import_plugin (arg )
199
206
200
207
def consider_conftest (self , conftestmodule ):
201
- if self .register (conftestmodule , name = conftestmodule .__file__ ):
208
+ if self .register (conftestmodule , name = conftestmodule .__file__ ,
209
+ conftest = True ):
202
210
self .consider_module (conftestmodule )
203
211
204
212
def consider_module (self , mod ):
@@ -233,12 +241,7 @@ def import_plugin(self, modname):
233
241
234
242
def listattr (self , attrname , plugins = None ):
235
243
if plugins is None :
236
- plugins = self ._plugins
237
- key = (attrname ,) + tuple (plugins )
238
- try :
239
- return list (self ._listattrcache [key ])
240
- except KeyError :
241
- pass
244
+ plugins = self ._plugins + self ._conftestplugins
242
245
l = []
243
246
last = []
244
247
wrappers = []
@@ -257,7 +260,7 @@ def listattr(self, attrname, plugins=None):
257
260
l .append (meth )
258
261
l .extend (last )
259
262
l .extend (wrappers )
260
- self ._listattrcache [key ] = list (l )
263
+ # self._listattrcache[key] = list(l)
261
264
return l
262
265
263
266
def call_plugin (self , plugin , methname , kwargs ):
@@ -397,6 +400,29 @@ def _addhooks(self, hookspecs, prefix):
397
400
raise ValueError ("did not find new %r hooks in %r" % (
398
401
prefix , hookspecs ,))
399
402
403
+ def _getcaller (self , name , plugins ):
404
+ caller = getattr (self , name )
405
+ methods = self ._pm .listattr (name , plugins = plugins )
406
+ return CachedHookCaller (caller , methods )
407
+
408
+
409
+ class CachedHookCaller :
410
+ def __init__ (self , hookmethod , methods ):
411
+ self .hookmethod = hookmethod
412
+ self .methods = methods
413
+
414
+ def __call__ (self , ** kwargs ):
415
+ return self .hookmethod ._docall (self .methods , kwargs )
416
+
417
+ def callextra (self , methods , ** kwargs ):
418
+ # XXX in theory we should respect "tryfirst/trylast" if set
419
+ # on the added methods but we currently only use it for
420
+ # pytest_generate_tests and it doesn't make sense there i'd think
421
+ all = self .methods
422
+ if methods :
423
+ all = all + methods
424
+ return self .hookmethod ._docall (all , kwargs )
425
+
400
426
401
427
class HookCaller :
402
428
def __init__ (self , hookrelay , name , firstresult ):
@@ -412,10 +438,6 @@ def __call__(self, **kwargs):
412
438
methods = self .hookrelay ._pm .listattr (self .name )
413
439
return self ._docall (methods , kwargs )
414
440
415
- def pcall (self , plugins , ** kwargs ):
416
- methods = self .hookrelay ._pm .listattr (self .name , plugins = plugins )
417
- return self ._docall (methods , kwargs )
418
-
419
441
def _docall (self , methods , kwargs ):
420
442
self .trace (self .name , kwargs )
421
443
self .trace .root .indent += 1
0 commit comments