123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- import pytest
- from pluggy import HookimplMarker
- from pluggy import HookspecMarker
- from pluggy import PluginManager
- hookspec = HookspecMarker("example")
- hookimpl = HookimplMarker("example")
- def test_parse_hookimpl_override() -> None:
- class MyPluginManager(PluginManager):
- def parse_hookimpl_opts(self, module_or_class, name):
- opts = PluginManager.parse_hookimpl_opts(self, module_or_class, name)
- if opts is None:
- if name.startswith("x1"):
- opts = {} # type: ignore[assignment]
- return opts
- class Plugin:
- def x1meth(self):
- pass
- @hookimpl(hookwrapper=True, tryfirst=True)
- def x1meth2(self):
- yield # pragma: no cover
- @hookimpl(wrapper=True, trylast=True)
- def x1meth3(self):
- return (yield) # pragma: no cover
- class Spec:
- @hookspec
- def x1meth(self):
- pass
- @hookspec
- def x1meth2(self):
- pass
- @hookspec
- def x1meth3(self):
- pass
- pm = MyPluginManager(hookspec.project_name)
- pm.register(Plugin())
- pm.add_hookspecs(Spec)
- hookimpls = pm.hook.x1meth.get_hookimpls()
- assert len(hookimpls) == 1
- assert not hookimpls[0].hookwrapper
- assert not hookimpls[0].wrapper
- assert not hookimpls[0].tryfirst
- assert not hookimpls[0].trylast
- assert not hookimpls[0].optionalhook
- hookimpls = pm.hook.x1meth2.get_hookimpls()
- assert len(hookimpls) == 1
- assert hookimpls[0].hookwrapper
- assert not hookimpls[0].wrapper
- assert hookimpls[0].tryfirst
- hookimpls = pm.hook.x1meth3.get_hookimpls()
- assert len(hookimpls) == 1
- assert not hookimpls[0].hookwrapper
- assert hookimpls[0].wrapper
- assert not hookimpls[0].tryfirst
- assert hookimpls[0].trylast
- def test_warn_when_deprecated_specified(recwarn) -> None:
- warning = DeprecationWarning("foo is deprecated")
- class Spec:
- @hookspec(warn_on_impl=warning)
- def foo(self):
- pass
- class Plugin:
- @hookimpl
- def foo(self):
- pass
- pm = PluginManager(hookspec.project_name)
- pm.add_hookspecs(Spec)
- with pytest.warns(DeprecationWarning) as records:
- pm.register(Plugin())
- (record,) = records
- assert record.message is warning
- assert record.filename == Plugin.foo.__code__.co_filename
- assert record.lineno == Plugin.foo.__code__.co_firstlineno
- def test_plugin_getattr_raises_errors() -> None:
- """Pluggy must be able to handle plugins which raise weird exceptions
- when getattr() gets called (#11).
- """
- class DontTouchMe:
- def __getattr__(self, x):
- raise Exception("can't touch me")
- class Module:
- pass
- module = Module()
- module.x = DontTouchMe() # type: ignore[attr-defined]
- pm = PluginManager(hookspec.project_name)
- # register() would raise an error
- pm.register(module, "donttouch")
- assert pm.get_plugin("donttouch") is module
- def test_not_all_arguments_are_provided_issues_a_warning(pm: PluginManager) -> None:
- """Calling a hook without providing all arguments specified in
- the hook spec issues a warning."""
- class Spec:
- @hookspec
- def hello(self, arg1, arg2):
- pass
- @hookspec(historic=True)
- def herstory(self, arg1, arg2):
- pass
- pm.add_hookspecs(Spec)
- with pytest.warns(UserWarning, match=r"'arg1', 'arg2'.*cannot be found.*$"):
- pm.hook.hello()
- with pytest.warns(UserWarning, match=r"'arg2'.*cannot be found.*$"):
- pm.hook.hello(arg1=1)
- with pytest.warns(UserWarning, match=r"'arg1'.*cannot be found.*$"):
- pm.hook.hello(arg2=2)
- with pytest.warns(UserWarning, match=r"'arg1', 'arg2'.*cannot be found.*$"):
- pm.hook.hello.call_extra([], kwargs=dict())
- with pytest.warns(UserWarning, match=r"'arg1', 'arg2'.*cannot be found.*$"):
- pm.hook.herstory.call_historic(kwargs=dict())
- def test_repr() -> None:
- class Plugin:
- @hookimpl
- def myhook(self):
- raise NotImplementedError()
- pm = PluginManager(hookspec.project_name)
- plugin = Plugin()
- pname = pm.register(plugin)
- assert repr(pm.hook.myhook.get_hookimpls()[0]) == (
- f"<HookImpl plugin_name={pname!r}, plugin={plugin!r}>"
- )
|