Skip to content

Commit

Permalink
Merge pull request #177 from Sup3rGeo/feature/get-plugins-for-hook
Browse files Browse the repository at this point in the history
Feature/get plugins for hook
  • Loading branch information
RonnyPfannschmidt committed Oct 14, 2018
2 parents 1da70c9 + a5c17ec commit 38988e9
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 5 deletions.
1 change: 1 addition & 0 deletions changelog/177.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add ``get_hookimpls()`` method to hook callers.
8 changes: 6 additions & 2 deletions pluggy/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,10 @@ def remove(wrappers):
if remove(self._nonwrappers) is None:
raise ValueError("plugin %r not found" % (plugin,))

def get_hookimpls(self):
# Order is important for _hookexec
return self._nonwrappers + self._wrappers

def _add_hookimpl(self, hookimpl):
"""Add an implementation to the callback chain.
"""
Expand Down Expand Up @@ -277,7 +281,7 @@ def __call__(self, *args, **kwargs):
"can not be found in this hook call".format(tuple(notincall)),
stacklevel=2,
)
return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
return self._hookexec(self, self.get_hookimpls(), kwargs)

def call_historic(self, result_callback=None, kwargs=None, proc=None):
"""Call the hook with given ``kwargs`` for all registered plugins and
Expand All @@ -299,7 +303,7 @@ def call_historic(self, result_callback=None, kwargs=None, proc=None):

self._call_history.append((kwargs or {}, result_callback))
# historizing hooks don't return results
res = self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
res = self._hookexec(self, self.get_hookimpls(), kwargs)
if result_callback is None:
return
# XXX: remember firstresult isn't compat with historic
Expand Down
6 changes: 3 additions & 3 deletions pluggy/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ def add_hookspecs(self, module_or_class):
else:
# plugins registered this hook without knowing the spec
hc.set_specification(module_or_class, spec_opts)
for hookfunction in hc._wrappers + hc._nonwrappers:
for hookfunction in hc.get_hookimpls():
self._verify_hook(hc, hookfunction)
names.append(name)

Expand Down Expand Up @@ -242,7 +242,7 @@ def check_pending(self):
if name[0] != "_":
hook = getattr(self.hook, name)
if not hook.has_spec():
for hookimpl in hook._wrappers + hook._nonwrappers:
for hookimpl in hook.get_hookimpls():
if not hookimpl.optionalhook:
raise PluginValidationError(
hookimpl.plugin,
Expand Down Expand Up @@ -329,7 +329,7 @@ def subset_hook_caller(self, name, remove_plugins):
hc = _HookCaller(
orig.name, orig._hookexec, orig.spec.namespace, orig.spec.opts
)
for hookimpl in orig._wrappers + orig._nonwrappers:
for hookimpl in orig.get_hookimpls():
plugin = hookimpl.plugin
if plugin not in plugins_to_remove:
hc._add_hookimpl(hookimpl)
Expand Down
32 changes: 32 additions & 0 deletions testing/test_pluginmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,38 @@ class PluginNo(object):
assert out == [10]


def test_get_hookimpls(pm):
class Hooks(object):
@hookspec
def he_method1(self, arg):
pass

pm.add_hookspecs(Hooks)
assert pm.hook.he_method1.get_hookimpls() == []

class Plugin1(object):
@hookimpl
def he_method1(self, arg):
pass

class Plugin2(object):
@hookimpl
def he_method1(self, arg):
pass

class PluginNo(object):
pass

plugin1, plugin2, plugin3 = Plugin1(), Plugin2(), PluginNo()
pm.register(plugin1)
pm.register(plugin2)
pm.register(plugin3)

hookimpls = pm.hook.he_method1.get_hookimpls()
hook_plugins = [item.plugin for item in hookimpls]
assert hook_plugins == [plugin1, plugin2]


def test_add_hookspecs_nohooks(pm):
with pytest.raises(ValueError):
pm.add_hookspecs(10)
Expand Down

0 comments on commit 38988e9

Please sign in to comment.