From 2e57d8660e47a5897dc1717cfeec4432090d9f75 Mon Sep 17 00:00:00 2001 From: Bruno Cauet Date: Tue, 13 Jan 2015 11:29:42 +0100 Subject: [PATCH] Ensure there's no duplicate plugin listeners A same function cannot be registered twice on a given event. This will permit improvements of some plugins (e.g. smartplaylist) --- beets/plugins.py | 3 ++- test/test_plugins.py | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/beets/plugins.py b/beets/plugins.py index d6cb6469e..193a209ab 100755 --- a/beets/plugins.py +++ b/beets/plugins.py @@ -185,7 +185,8 @@ class BeetsPlugin(object): """ if cls.listeners is None: cls.listeners = defaultdict(list) - cls.listeners[event].append(func) + if func not in cls.listeners[event]: + cls.listeners[event].append(func) @classmethod def listen(cls, event): diff --git a/test/test_plugins.py b/test/test_plugins.py index 0880e2d27..256fc2ff4 100644 --- a/test/test_plugins.py +++ b/test/test_plugins.py @@ -161,6 +161,41 @@ class HelpersTest(unittest.TestCase): ('A', 'B', 'C', 'D')), ['D', 'B', 'C', 'A']) +class ListenersTest(unittest.TestCase, TestHelper): + def setUp(self): + self.setup_plugin_loader() + + def tearDown(self): + self.teardown_plugin_loader() + self.teardown_beets() + + def test_register(self): + + class DummyPlugin(plugins.BeetsPlugin): + def __init__(self): + super(DummyPlugin, self).__init__() + self.register_listener('cli_exit', self.dummy) + self.register_listener('cli_exit', self.dummy) + + def dummy(self): + pass + + d = DummyPlugin() + self.assertEqual(DummyPlugin.listeners['cli_exit'], [d.dummy]) + + d2 = DummyPlugin() + DummyPlugin.register_listener('cli_exit', d.dummy) + self.assertEqual(DummyPlugin.listeners['cli_exit'], + [d.dummy, d2.dummy]) + + @DummyPlugin.listen('cli_exit') + def dummy(lib): + pass + + self.assertEqual(DummyPlugin.listeners['cli_exit'], + [d.dummy, d2.dummy, dummy]) + + def suite(): return unittest.TestLoader().loadTestsFromName(__name__)