diff --git a/beets/plugins.py b/beets/plugins.py index 7998895c6..f242a7073 100644 --- a/beets/plugins.py +++ b/beets/plugins.py @@ -399,15 +399,15 @@ def _get_plugin(name: str) -> BeetsPlugin | None: if len(plugin_classes) > 1: warnings.warn( - f"Plugin {name} defines multiple plugin classes; " - f"using the first one found ({plugin_classes[0].__name__})." + f"Plugin '{name}' defines multiple plugin classes; " + f"using the first one found ({plugin_classes[0].__name__}). " f"This will become an error in beets 3.0.0. Consider exporting " f"the desired plugin class explicitly using `__all__`.", DeprecationWarning, stacklevel=2, ) - if len(plugin_classes) == 1: + if len(plugin_classes) != 0: return plugin_classes[0]() except Exception: diff --git a/test/test_plugins.py b/test/test_plugins.py index df338f924..d30425bbd 100644 --- a/test/test_plugins.py +++ b/test/test_plugins.py @@ -19,6 +19,7 @@ import logging import os import pkgutil import sys +from types import ModuleType from unittest.mock import ANY, Mock, patch import pytest @@ -523,3 +524,40 @@ class TestImportPlugin(PluginMixin): assert "PluginImportError" not in caplog.text, ( f"Plugin '{plugin_name}' has issues during import." ) + + +class MultiPluginModule(ModuleType): + class DummyPlugin1(plugins.BeetsPlugin): + pass + + class DummyPlugin2(plugins.BeetsPlugin): + pass + + def __init__(self, *_, **__): + module_name = "beetsplug.multi_export" + super().__init__(module_name) + self.DummyPlugin1.__module__ = module_name + self.DummyPlugin1 = self.DummyPlugin1 + self.DummyPlugin2 = self.DummyPlugin2 + self.DummyPlugin2.__module__ = module_name + + +class TestMultiPluginExport(PluginMixin): + """Test that exporting multiple plugins from a single namespace + raises a warning. + + TODO: Change to raises an error on migration to 3.0.0 + """ + + plugin = "multi_export" + + @pytest.fixture(autouse=True, scope="class") + def setup(self): + with patch.dict( + sys.modules, {"beetsplug.multi_export": MultiPluginModule()} + ): + yield + + def test_multi_plugin_export(self): + with pytest.deprecated_call(): + self.load_plugins("multi_export")