diff --git a/_pytest/config.py b/_pytest/config.py index fcb045644..ec34e7954 100644 --- a/_pytest/config.py +++ b/_pytest/config.py @@ -197,6 +197,7 @@ class PytestPluginManager(PluginManager): if conftestpath.check(file=1): mod = self._importconftest(conftestpath) clist.append(mod) + self._path2confmods[path] = clist return clist @@ -220,6 +221,7 @@ class PytestPluginManager(PluginManager): mod = conftestpath.pyimport() except Exception: raise ConftestImportFailure(conftestpath, sys.exc_info()) + self._conftestpath2mod[conftestpath] = mod dirpath = conftestpath.dirpath() if dirpath in self._path2confmods: diff --git a/_pytest/core.py b/_pytest/core.py index 2a2ba1b7d..acc6183e5 100644 --- a/_pytest/core.py +++ b/_pytest/core.py @@ -236,6 +236,21 @@ class PluginManager(object): 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): """ Return a new HookCaller instance which manages calls to all methods named "name" in the plugins. The new hook caller diff --git a/_pytest/main.py b/_pytest/main.py index 4545aa6f6..38774c50d 100644 --- a/_pytest/main.py +++ b/_pytest/main.py @@ -362,9 +362,6 @@ class Node(object): def listnames(self): return [x.name for x in self.listchain()] - def getplugins(self): - return self.config._getmatchingplugins(self.fspath) - def addfinalizer(self, fin): """ register a function to be called when this node is finalized. diff --git a/testing/test_core.py b/testing/test_core.py index 5fef02f74..295df0d2e 100644 --- a/testing/test_core.py +++ b/testing/test_core.py @@ -195,6 +195,44 @@ class TestPluginManager: hc(arg=2) 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: @pytest.fixture