From b0846f914e164a75cfb70cff3c47c587a3fa041b Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Tue, 3 Mar 2015 08:53:58 +0100 Subject: [PATCH] Fix crash for commands with ambiguous getopts shortcuts and no docstring. Signed-off-by: James McCoy --- src/callbacks.py | 2 +- test/test_commands.py | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/callbacks.py b/src/callbacks.py index b52d3e726..52c46d044 100644 --- a/src/callbacks.py +++ b/src/callbacks.py @@ -1207,7 +1207,7 @@ class Commands(BasePlugin): utils.exnToString(e)) help = self.getCommandHelp(command) if help.endswith('command has no help.'): - irc.error('Invalid arguments for %s.' % method.__name__) + irc.error('Invalid arguments for %s.' % formatCommand(command)) else: irc.reply(help) except (SyntaxError, Error), e: diff --git a/test/test_commands.py b/test/test_commands.py index cc94c8c1f..c23d5c779 100644 --- a/test/test_commands.py +++ b/test/test_commands.py @@ -28,6 +28,8 @@ # POSSIBILITY OF SUCH DAMAGE. ### +import getopt + from supybot.test import * from supybot.commands import * @@ -117,6 +119,17 @@ class GeneralContextTestCase(CommandsTestCase): ['12', '--foo', 'baz', '--bar', '13', '15'], [12, [('foo', 'baz'), ('bar', 13)], 15]) + def testGetoptsShort(self): + spec = ['int', getopts({'foo': None, 'bar': 'int'}), 'int'] + self.assertState(spec, + ['12', '--f', 'baz', '--ba', '13', '15'], + [12, [('foo', 'baz'), ('bar', 13)], 15]) + + def testGetoptsConflict(self): + spec = ['int', getopts({'foo': None, 'fbar': 'int'}), 'int'] + self.assertRaises(getopt.GetoptError, self.assertStateErrored, + spec, ['12', '--f', 'baz', '--ba', '13', '15']) + def testAny(self): self.assertState([any('int')], ['1', '2', '3'], [[1, 2, 3]]) self.assertState([None, any('int')], ['1', '2', '3'], ['1', [2, 3]]) @@ -186,5 +199,19 @@ class FirstTestCase(CommandsTestCase): spec = [first('regexpMatcher', 'regexpReplacer'), 'text'] self.assertStateErrored(spec, ['s/foo/bar/', 'x' * 512], errored=False) +class GetoptTestCase(PluginTestCase): + plugins = ('Misc',) # We put something so it does not complain + class Foo(callbacks.Plugin): + def bar(self, irc, msg, args, optlist): + irc.reply(' '.join(sorted(['%s:%d'%x for x in optlist]))) + bar = wrap(bar, [getopts({'foo': 'int', 'fbar': 'int'})]) + + def testGetoptsExact(self): + self.irc.addCallback(self.Foo(self.irc)) + self.assertResponse('bar --foo 3 --fbar 4', 'fbar:4 foo:3') + self.assertResponse('bar --fo 3 --fb 4', 'fbar:4 foo:3') + self.assertResponse('bar --f 3 --fb 5', + 'Error: Invalid arguments for bar.') + # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: