def dummy_plugin_manager(): plugin_manager = PluginManager("dummy") plugin_manager.add_hookspecs(MySpec) plugin_manager.register(p1, name='p1') plugin_manager.register(p2, name='p2') plugin_manager.register(p3, name='p3') plugin_manager.register(wrapper, name='wrapper') return plugin_manager
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_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
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_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
from ..types import AugmentedWidget from ..utils._appdirs import user_site_packages from ..utils.misc import camel_to_spaces, running_as_bundled_app from . import _builtins, hook_specifications if sys.platform.startswith('linux') and running_as_bundled_app(): sys.path.append(user_site_packages()) if TYPE_CHECKING: from magicgui.widgets import FunctionGui from qtpy.QtWidgets import QWidget # the main plugin manager instance for the `napari` plugin namespace. plugin_manager = PluginManager('napari', discover_entry_point='napari.plugin') with plugin_manager.discovery_blocked(): plugin_manager.add_hookspecs(hook_specifications) plugin_manager.register(_builtins, name='builtins') WidgetCallable = Callable[..., Union['FunctionGui', 'QWidget']] dock_widgets: Dict[ str, Dict[str, Tuple[WidgetCallable, Dict[str, Any]]] ] = dict() function_widgets: Dict[str, Dict[str, Callable[..., Any]]] = dict() def register_dock_widget( args: Union[AugmentedWidget, List[AugmentedWidget]], hookimpl: HookImplementation, ):
def pm(): from napari_plugin_engine import PluginManager pm = PluginManager(project_name='example') return pm
def test_plugin_manager() -> PluginManager: """A plugin manager fixture with the project name 'test'.""" return PluginManager(project_name='test')