1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
|
import warnings
import pytest
from napari_plugin_engine import (
HookImplementationMarker,
HookSpecificationMarker,
PluginManager,
)
hookspec = HookSpecificationMarker("example")
hookimpl = HookImplementationMarker("example")
def test_warn_when_deprecated_specified(recwarn):
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():
"""napari_plugin_engine must be able to handle plugins which raise weird exceptions
when getattr() gets called (#11).
"""
class DontTouchMe:
def __getattr__(self, x):
raise Exception("cant touch me")
class Module:
pass
module = Module()
module.x = DontTouchMe()
pm = PluginManager(hookspec.project_name)
# register() would raise an error
pm.register(module, "donttouch")
assert pm.plugins.get("donttouch") is module
def test_warning_on_call_vs_hookspec_arg_mismatch():
"""Verify that is a hook is called with less arguments then defined in the
spec that a warning is emitted.
"""
class Spec:
@hookspec
def myhook(self, arg1, arg2):
pass
class Plugin:
@hookimpl
def myhook(self, arg1):
pass
pm = PluginManager(hookspec.project_name)
pm.register(Plugin())
pm.add_hookspecs(Spec())
with warnings.catch_warnings(record=True) as warns:
warnings.simplefilter("always")
# calling should trigger a warning
pm.hook.myhook(arg1=1)
assert len(warns) == 1
warning = warns[-1]
assert issubclass(warning.category, Warning)
assert "Argument(s) ('arg2',)" in str(warning.message)
def test_repr():
class Hook:
@hookspec
def myhook(arg):
...
class Plugin:
@hookimpl
def myhook(arg):
raise NotImplementedError()
pm = PluginManager(hookspec.project_name)
pm.add_hookspecs(Hook)
assert (
repr(pm.hook.myhook.spec)
== "<HookSpecification 'myhook' args=('arg',)>"
)
plugin = Plugin()
pname = pm.register(plugin)
expected = f"<HookImplementation plugin={pname!r} spec='myhook'>"
assert repr(pm.hook.myhook._nonwrappers[0]) == expected
|