diff --git a/picard/script.py b/picard/script.py index f7520abb5..139ce688e 100644 --- a/picard/script.py +++ b/picard/script.py @@ -92,18 +92,23 @@ class ScriptFunction(object): try: argnum_bound = parser.functions[name].argcount argcount = len(args) - if argnum_bound and not (argnum_bound.lower <= argcount - and (argnum_bound.upper is None - or len(args) <= argnum_bound.upper)): - raise ScriptError( - "Wrong number of arguments for $%s: Expected %s, got %i at position %i, line %i" - % (name, - str(argnum_bound.lower) - if argnum_bound.upper is None - else "%i - %i" % (argnum_bound.lower, argnum_bound.upper), - argcount, - parser._x, - parser._y)) + if argnum_bound: + too_few_args = argcount < argnum_bound.lower + if argnum_bound.upper is not None: + if argnum_bound.lower == argnum_bound.upper: + expected = "exactly %i" % argnum_bound.lower + else: + expected = "between %i and %i" % (argnum_bound.lower, argnum_bound.upper) + too_many_args = argcount > argnum_bound.upper + else: + expected = "at least %i" % argnum_bound.lower + too_many_args = False + + if too_few_args or too_many_args: + raise ScriptError( + "Wrong number of arguments for $%s: Expected %s, got %i at position %i, line %i" + % (name, expected, argcount, parser._x, parser._y) + ) except KeyError: raise ScriptUnknownFunction("Unknown function '%s'" % name) diff --git a/test/test_script.py b/test/test_script.py index d3eddd5d8..136040b20 100644 --- a/test/test_script.py +++ b/test/test_script.py @@ -385,10 +385,29 @@ class ScriptParserTest(PicardTestCase): self.assertEqual(result, u'artist/title') def test_cmd_with_not_arguments(self): - try: - self.parser.eval("$noargstest()") - except ScriptError: - self.fail("Function noargs raised ScriptError unexpectedly.") + self.parser.eval("$noargstest()") + + def test_cmd_with_wrong_argcount_or(self): + # $or() requires at least 2 arguments + areg = r"^Wrong number of arguments for \$or: Expected at least 2, " + with self.assertRaisesRegex(ScriptError, areg): + self.parser.eval('$or(0)') + + def test_cmd_with_wrong_argcount_eq(self): + # $eq() requires exactly 2 arguments + areg = r"^Wrong number of arguments for \$eq: Expected exactly 2, " + with self.assertRaisesRegex(ScriptError, areg): + self.parser.eval('$eq(0)') + with self.assertRaisesRegex(ScriptError, areg): + self.parser.eval('$eq(0,0,0)') + + def test_cmd_with_wrong_argcount_if(self): + areg = r"^Wrong number of arguments for \$if: Expected between 2 and 3, " + # $if() requires 2 or 3 arguments + with self.assertRaisesRegex(ScriptError, areg): + self.parser.eval('$if(1)') + with self.assertRaisesRegex(ScriptError, areg): + self.parser.eval('$if(1,a,b,c)') def test_cmd_unset_simple(self): context = Metadata()