diff --git a/beets/plugins.py b/beets/plugins.py index a4205e10d..2b68f2d02 100755 --- a/beets/plugins.py +++ b/beets/plugins.py @@ -262,12 +262,11 @@ def types(model_cls): for plugin in find_plugins(): plugin_types = getattr(plugin, attr_name, {}) for field in plugin_types: - if field in types: + if field in types and plugin_types[field] != types[field]: raise PluginConflictException( u'Plugin {0} defines flexible field {1} ' - 'which has already been defined.'.format( - plugin.name, field - ) + 'which has already been defined with ' + 'another type.'.format(plugin.name, field) ) types.update(plugin_types) return types diff --git a/test/test_plugins.py b/test/test_plugins.py index dd6b27942..80285a688 100644 --- a/test/test_plugins.py +++ b/test/test_plugins.py @@ -112,6 +112,45 @@ class ItemWriteTest(unittest.TestCase, TestHelper): self.event_listener_plugin.register_listener(event, func) +class ItemTypeConflictTest(unittest.TestCase, TestHelper): + + def setUp(self): + self.setup_plugin_loader() + self.setup_beets() + + def tearDown(self): + self.teardown_plugin_loader() + self.teardown_beets() + + def test_mismatch(self): + class EventListenerPlugin(plugins.BeetsPlugin): + item_types = {'duplicate': types.INTEGER} + + class AdventListenerPlugin(plugins.BeetsPlugin): + item_types = {'duplicate': types.FLOAT} + + self.event_listener_plugin = EventListenerPlugin + self.advent_listener_plugin = AdventListenerPlugin + self.register_plugin(EventListenerPlugin) + self.register_plugin(AdventListenerPlugin) + self.assertRaises(plugins.PluginConflictException, + plugins.types, Item + ) + + def test_match(self): + class EventListenerPlugin(plugins.BeetsPlugin): + item_types = {'duplicate': types.INTEGER} + + class AdventListenerPlugin(plugins.BeetsPlugin): + item_types = {'duplicate': types.INTEGER} + + self.event_listener_plugin = EventListenerPlugin + self.advent_listener_plugin = AdventListenerPlugin + self.register_plugin(EventListenerPlugin) + self.register_plugin(AdventListenerPlugin) + self.assertNotEqual(None, plugins.types(Item)) + + def suite(): return unittest.TestLoader().loadTestsFromName(__name__)