From 6f9960d7a4ec4ae2e0eb7ebe82006a1d5c91d554 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. --- src/callbacks.py | 2 +- test/test_commands.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/callbacks.py b/src/callbacks.py index a0524a20c..53a3d6503 100644 --- a/src/callbacks.py +++ b/src/callbacks.py @@ -1288,7 +1288,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.') % ' '.join(command)) else: irc.reply(help) except (SyntaxError, Error) as e: diff --git a/test/test_commands.py b/test/test_commands.py index e19f7399b..76d51e9f6 100644 --- a/test/test_commands.py +++ b/test/test_commands.py @@ -28,6 +28,7 @@ ### import sys +import getopt from supybot.test import * @@ -119,6 +120,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]]) @@ -184,5 +196,21 @@ class FirstTestCase(CommandsTestCase): self.assertStateErrored([first('int', 'something')], ['words'], 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'})], + checkDoc=False) + + 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: