def get_serializers(refresh_cache=False): """Discover and return Serializer classes from all installed plugins Serializers are cached and are not repeatedly loaded in future calls Args: refresh_cache (bool): If True, ignore any existing serializer cache and discover serializers as normal Returns: dict: Keys are the formats provided by and pointing to their respective Serializers """ global _serializer_cache if _serializer_cache is None or refresh_cache: from pluggy import PluginManager package_name = __name__.split('.')[0] pm = PluginManager(package_name) pm.load_setuptools_entrypoints(package_name + '.serializers') for mod in pm.get_plugins(): import_submodules(mod) _serializer_cache = {} for serializer_class in get_recursive_subclasses(Serializer): if not serializer_class.format: logger.warning( 'Serializer "{}" does not provide a format, will not be auto-discovered' .format(get_full_qualname(serializer_class))) continue _serializer_cache[serializer_class.format] = serializer_class return _serializer_cache
def test_pm_name(pm: PluginManager) -> None: class A: pass a1 = A() name = pm.register(a1, name="hello") assert name == "hello" pm.unregister(a1) assert pm.get_plugin("hello") is None assert not pm.is_registered(a1) assert not pm.get_plugins() name2 = pm.register(a1, name="hello") assert name2 == name pm.unregister(name="hello") assert pm.get_plugin("hello") is None assert not pm.is_registered(a1) assert not pm.get_plugins()
def test_register(pm: PluginManager) -> None: class MyPlugin: @hookimpl def he_method1(self): ... my = MyPlugin() pm.register(my) assert pm.get_plugins() == {my} my2 = MyPlugin() pm.register(my2) assert pm.get_plugins() == {my, my2} assert pm.is_registered(my) assert pm.is_registered(my2) pm.unregister(my) assert not pm.is_registered(my) assert pm.get_plugins() == {my2} with pytest.raises(AssertionError, match=r"not registered"): pm.unregister(my)
def _register_hooks_setuptools(hook_manager: PluginManager, disabled_plugins: Iterable[str]) -> None: """Register pluggy hooks from setuptools entrypoints. Args: hook_manager: Hook manager instance to register the hooks with. disabled_plugins: An iterable returning the names of plugins which hooks must not be registered; any already registered hooks will be unregistered. """ already_registered = hook_manager.get_plugins() found = hook_manager.load_setuptools_entrypoints(_PLUGIN_HOOKS) disabled_plugins = set(disabled_plugins) # Get list of plugin/distinfo tuples for all setuptools registered plugins. plugininfo = hook_manager.list_plugin_distinfo() plugin_names = set() disabled_plugin_names = set() for plugin, dist in plugininfo: if dist.project_name in disabled_plugins: # `unregister()` is used instead of `set_blocked()` because # we want to disable hooks for specific plugin based on project # name and not `entry_point` name. Also, we log project names with # version for which hooks were registered. hook_manager.unregister(plugin=plugin) found -= 1 disabled_plugin_names.add(f"{dist.project_name}-{dist.version}") elif plugin not in already_registered: plugin_names.add(f"{dist.project_name}-{dist.version}") if disabled_plugin_names: logging.info( "Hooks are disabled for plugin(s): %s", ", ".join(sorted(disabled_plugin_names)), ) if plugin_names: logging.info( "Registered hooks from %d installed plugin(s): %s", found, ", ".join(sorted(plugin_names)), )
def test_pm(pm: PluginManager) -> None: """Basic registration with objects""" class A: pass a1, a2 = A(), A() pm.register(a1) assert pm.is_registered(a1) pm.register(a2, "hello") assert pm.is_registered(a2) out = pm.get_plugins() assert a1 in out assert a2 in out assert pm.get_plugin("hello") == a2 assert pm.unregister(a1) == a1 assert not pm.is_registered(a1) out2 = pm.list_name_plugin() assert len(out2) == 1 assert out2 == [("hello", a2)]