specialize make_hook_caller to work with a subset of the registered plugins.

--HG--
branch : more_plugin
This commit is contained in:
holger krekel 2015-04-25 22:13:42 +02:00
parent a042c57227
commit d422247433
4 changed files with 55 additions and 3 deletions

View File

@ -197,6 +197,7 @@ class PytestPluginManager(PluginManager):
if conftestpath.check(file=1): if conftestpath.check(file=1):
mod = self._importconftest(conftestpath) mod = self._importconftest(conftestpath)
clist.append(mod) clist.append(mod)
self._path2confmods[path] = clist self._path2confmods[path] = clist
return clist return clist
@ -220,6 +221,7 @@ class PytestPluginManager(PluginManager):
mod = conftestpath.pyimport() mod = conftestpath.pyimport()
except Exception: except Exception:
raise ConftestImportFailure(conftestpath, sys.exc_info()) raise ConftestImportFailure(conftestpath, sys.exc_info())
self._conftestpath2mod[conftestpath] = mod self._conftestpath2mod[conftestpath] = mod
dirpath = conftestpath.dirpath() dirpath = conftestpath.dirpath()
if dirpath in self._path2confmods: if dirpath in self._path2confmods:

View File

@ -236,6 +236,21 @@ class PluginManager(object):
return TracedHookExecution(self, before, after).undo return TracedHookExecution(self, before, after).undo
def subset_hook_caller(self, name, remove_plugins):
""" Return a new HookCaller instance which manages calls to
the plugins but without hooks from remove_plugins taking part. """
hc = getattr(self.hook, name)
plugins_to_remove = [plugin for plugin in remove_plugins
if hasattr(plugin, name)]
if plugins_to_remove:
hc = hc.clone()
for plugin in plugins_to_remove:
hc._remove_plugin(plugin)
# we also keep track of this hook caller so it
# gets properly removed on plugin unregistration
self._plugin2hookcallers.setdefault(plugin, []).append(hc)
return hc
def make_hook_caller(self, name, plugins): def make_hook_caller(self, name, plugins):
""" Return a new HookCaller instance which manages calls to """ Return a new HookCaller instance which manages calls to
all methods named "name" in the plugins. The new hook caller all methods named "name" in the plugins. The new hook caller

View File

@ -362,9 +362,6 @@ class Node(object):
def listnames(self): def listnames(self):
return [x.name for x in self.listchain()] return [x.name for x in self.listchain()]
def getplugins(self):
return self.config._getmatchingplugins(self.fspath)
def addfinalizer(self, fin): def addfinalizer(self, fin):
""" register a function to be called when this node is finalized. """ register a function to be called when this node is finalized.

View File

@ -195,6 +195,44 @@ class TestPluginManager:
hc(arg=2) hc(arg=2)
assert l == [10] assert l == [10]
def test_subset_hook_caller(self, pm):
class Hooks:
def he_method1(self, arg):
pass
pm.addhooks(Hooks)
l = []
class Plugin1:
def he_method1(self, arg):
l.append(arg)
class Plugin2:
def he_method1(self, arg):
l.append(arg*10)
class PluginNo:
pass
plugin1, plugin2, plugin3 = Plugin1(), Plugin2(), PluginNo()
pm.register(plugin1)
pm.register(plugin2)
pm.register(plugin3)
pm.hook.he_method1(arg=1)
assert l == [10, 1]
l[:] = []
hc = pm.subset_hook_caller("he_method1", [plugin1])
hc(arg=2)
assert l == [20]
l[:] = []
hc = pm.subset_hook_caller("he_method1", [plugin2])
hc(arg=2)
assert l == [2]
l[:] = []
pm.unregister(plugin1)
hc(arg=2)
assert l == []
class TestAddMethodOrdering: class TestAddMethodOrdering:
@pytest.fixture @pytest.fixture