properly perform hook calls with extra methods

--HG--
branch : more_plugin
This commit is contained in:
holger krekel 2015-04-25 11:29:11 +02:00
parent a63585dcab
commit 2f8a1aed6e
3 changed files with 37 additions and 10 deletions

View File

@ -447,7 +447,7 @@ class HookRelay:
self.trace = pm.trace.root.get("hook") self.trace = pm.trace.root.get("hook")
class HookCaller: class HookCaller(object):
def __init__(self, name, plugins, argnames=None, firstresult=None, def __init__(self, name, plugins, argnames=None, firstresult=None,
historic=False): historic=False):
self.name = name self.name = name
@ -462,6 +462,17 @@ class HookCaller:
if self.historic: if self.historic:
self._call_history = [] self._call_history = []
def clone(self):
hc = object.__new__(HookCaller)
hc.name = self.name
hc.plugins = self.plugins
hc.historic = self.historic
hc.argnames = self.argnames
hc.firstresult = self.firstresult
hc.wrappers = list(self.wrappers)
hc.nonwrappers = list(self.nonwrappers)
return hc
@property @property
def pre(self): def pre(self):
return self.argnames is None return self.argnames is None
@ -511,8 +522,10 @@ class HookCaller:
def callextra(self, methods, **kwargs): def callextra(self, methods, **kwargs):
assert not self.historic assert not self.historic
return self._docall(self.nonwrappers + methods + self.wrappers, hc = self.clone()
kwargs) for method in methods:
hc.add_method(method)
return hc(**kwargs)
def _docall(self, methods, kwargs): def _docall(self, methods, kwargs):
return MultiCall(methods, kwargs, firstresult=self.firstresult).execute() return MultiCall(methods, kwargs, firstresult=self.firstresult).execute()
@ -521,10 +534,11 @@ class HookCaller:
self._call_history.append((kwargs, proc)) self._call_history.append((kwargs, proc))
self._docall(self.nonwrappers + self.wrappers, kwargs) self._docall(self.nonwrappers + self.wrappers, kwargs)
def _apply_history(self, meth): def _apply_history(self, method):
if hasattr(self, "_call_history"): if hasattr(self, "_call_history"):
for kwargs, proc in self._call_history: for kwargs, proc in self._call_history:
res = MultiCall([meth], kwargs, firstresult=True).execute() args = [kwargs[argname] for argname in varnames(method)]
res = method(*args)
if proc is not None: if proc is not None:
proc(res) proc(res)

View File

@ -375,13 +375,15 @@ class PyCollector(PyobjMixin, pytest.Collector):
fixtureinfo = fm.getfixtureinfo(self, funcobj, cls) fixtureinfo = fm.getfixtureinfo(self, funcobj, cls)
metafunc = Metafunc(funcobj, fixtureinfo, self.config, metafunc = Metafunc(funcobj, fixtureinfo, self.config,
cls=cls, module=module) cls=cls, module=module)
try:
methods = [module.pytest_generate_tests]
except AttributeError:
methods = [] methods = []
if hasattr(module, "pytest_generate_tests"):
methods.append(module.pytest_generate_tests)
if hasattr(cls, "pytest_generate_tests"): if hasattr(cls, "pytest_generate_tests"):
methods.append(cls().pytest_generate_tests) methods.append(cls().pytest_generate_tests)
if methods:
self.ihook.pytest_generate_tests.callextra(methods, metafunc=metafunc) self.ihook.pytest_generate_tests.callextra(methods, metafunc=metafunc)
else:
self.ihook.pytest_generate_tests(metafunc=metafunc)
Function = self._getcustomclass("Function") Function = self._getcustomclass("Function")
if not metafunc._calls: if not metafunc._calls:

View File

@ -129,7 +129,18 @@ class TestPluginManager:
return arg * 10 return arg * 10
pm.register(Plugin()) pm.register(Plugin())
assert l == [10]
def test_call_extra(self, pm):
class Hooks:
def he_method1(self, arg):
pass
pm.addhooks(Hooks)
def he_method1(arg):
return arg * 10
l = pm.hook.he_method1.callextra([he_method1], arg=1)
assert l == [10] assert l == [10]