diff --git a/changelog/807.bugfix.rst b/changelog/807.bugfix.rst new file mode 100644 index 00000000..8aa4e94d --- /dev/null +++ b/changelog/807.bugfix.rst @@ -0,0 +1 @@ +Fix :meth:`~pluggy.PluginManager.load_setuptools_entrypoints` crashing distribution listing when an entry point is declined during registration. diff --git a/src/pluggy/_manager.py b/src/pluggy/_manager.py index 2697705b..f9cb47dc 100644 --- a/src/pluggy/_manager.py +++ b/src/pluggy/_manager.py @@ -517,8 +517,10 @@ def load_setuptools_entrypoints(self, group: str, name: str | None = None) -> in ): continue plugin = ep.load() - self.register(plugin, name=ep.name) - self._name2dist[ep.name] = dist + plugin_name = self.register(plugin, name=ep.name) + if plugin_name is None: + continue + self._name2dist[plugin_name] = dist count += 1 return count diff --git a/testing/test_pluginmanager.py b/testing/test_pluginmanager.py index 7de6c6de..f145a27c 100644 --- a/testing/test_pluginmanager.py +++ b/testing/test_pluginmanager.py @@ -993,6 +993,44 @@ class Distribution: assert pm.list_plugin_distributions() == [(a, dist)] +def test_load_setuptools_ignores_declined_plugins( + monkeypatch: pytest.MonkeyPatch, +) -> None: + class EntryPoint: + group = "hello" + + def __init__(self, name: str, plugin: object) -> None: + self.name = name + self.plugin = plugin + + def load(self) -> object: + return self.plugin + + accepted = object() + + class Distribution: + entry_points = ( + EntryPoint("none-plugin", None), + EntryPoint("declined", object()), + EntryPoint("renamed", accepted), + ) + + class DecliningPluginManager(PluginManager): + def register(self, plugin: object, name: str | None = None) -> str | None: + if name == "declined": + return None + if name == "renamed": + name = "accepted" + return super().register(plugin, name) + + dist = cast(importlib.metadata.Distribution, Distribution()) + monkeypatch.setattr(importlib.metadata, "distributions", lambda: (dist,)) + pm = DecliningPluginManager("example") + + assert pm.load_setuptools_entrypoints("hello") == 1 + assert pm.list_plugin_distributions() == [(accepted, dist)] + + def test_add_tracefuncs(he_pm: PluginManager) -> None: out: list[Any] = []