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)
This commit is contained in:
Bruno Cauet 2015-01-13 11:29:42 +01:00
parent c8309cbe57
commit 2e57d8660e
2 changed files with 37 additions and 1 deletions

View file

@ -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):

View file

@ -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__)