diff --git a/classes.py b/classes.py index d514da9..c963d9d 100644 --- a/classes.py +++ b/classes.py @@ -1223,6 +1223,10 @@ class PyLinkNetworkCoreWithUtils(PyLinkNetworkCore): log.debug("(%s) reverse_modes: skipping reversing '%s %s' with %s since it " "wasn't previously set.", self.name, char, arg, mpair) continue + elif mpair in newmodes: + # Check the same for regular modes that previously didn't exist + log.debug("(%s) reverse_modes: skipping duplicate reverse mode %s", self.name, mpair) + continue newmodes.append(mpair) log.debug('(%s) reverse_modes: new modes: %s', self.name, newmodes) diff --git a/test/protocol_test_fixture.py b/test/protocol_test_fixture.py index b50b5d5..fe8409a 100644 --- a/test/protocol_test_fixture.py +++ b/test/protocol_test_fixture.py @@ -761,4 +761,29 @@ class BaseProtocolTest(unittest.TestCase): out = self.p.reverse_modes('#weirdstuff', '-b+b *!*@* *!*@*') # -+ cycle existing ban self.assertEqual(out, '-b *!*@*') # Ugly but OK + def test_reverse_modes_cycle_arguments(self): + # All of these cases are ugly, sometimes unsetting modes that don't exist... + c = self.p.channels['#weirdstuff'] = Channel(self.p, name='#weirdstuff') + + out = self.p.reverse_modes('#weirdstuff', '+l-l 30') + self.assertEqual(out, '-l') + out = self.p.reverse_modes('#weirdstuff', '-l+l 30') + self.assertEqual(out, '-l') + + out = self.p.reverse_modes('#weirdstuff', '+k-k aaaaaaaaaaaa aaaaaaaaaaaa') + self.assertEqual(out, '-k aaaaaaaaaaaa') + out = self.p.reverse_modes('#weirdstuff', '-k+k aaaaaaaaaaaa aaaaaaaaaaaa') + self.assertEqual(out, '-k aaaaaaaaaaaa') + + c.modes = {('l', '555'), ('k', 'NO-PLEASE')} + out = self.p.reverse_modes('#weirdstuff', '+l-l 30') + self.assertEqual(out, '+l 555') + out = self.p.reverse_modes('#weirdstuff', '-l+l 30') + self.assertEqual(out, '+l 555') + + out = self.p.reverse_modes('#weirdstuff', '+k-k aaaaaaaaaaaa aaaaaaaaaaaa') + self.assertEqual(out, '+k NO-PLEASE') + out = self.p.reverse_modes('#weirdstuff', '-k+k aaaaaaaaaaaa aaaaaaaaaaaa') + self.assertEqual(out, '+k NO-PLEASE') + # TODO: test type coersion if channel or mode targets are ints