Author: Armin Rigo <ar...@tunes.org> Branch: py3k Changeset: r87329:37ab7781ce67 Date: 2016-09-22 17:48 +0200 http://bitbucket.org/pypy/pypy/changeset/37ab7781ce67/
Log: Test and fix: correctly count the number of kwonly argument given, for the error message diff --git a/pypy/interpreter/argument.py b/pypy/interpreter/argument.py --- a/pypy/interpreter/argument.py +++ b/pypy/interpreter/argument.py @@ -198,7 +198,6 @@ input_argcount += take # collect extra positional arguments into the *vararg - kwonly_given = 0 if signature.has_vararg(): args_left = co_argcount - upfront if args_left < 0: # check required by rpython @@ -212,9 +211,6 @@ loc = co_argcount + co_kwonlyargcount scope_w[loc] = self.space.newtuple(starargs_w) elif avail > co_argcount: - for i in range(co_argcount, co_argcount + co_kwonlyargcount): - if scope_w[i] is None: - kwonly_given += 1 too_many_args = True # if a **kwargs argument is needed, create the dict @@ -250,16 +246,13 @@ else: raise ArgErrUnknownKwds(self.space, num_remainingkwds, keywords, kwds_mapping, self.keyword_names_w) - if too_many_args: - raise ArgErrTooMany(signature.num_argnames(), - 0 if defaults_w is None else len(defaults_w), - avail, kwonly_given) # check for missing arguments and fill them from the kwds, # or with defaults, if available missing_positional = [] missing_kwonly = [] - if input_argcount < co_argcount + co_kwonlyargcount: + more_filling = (input_argcount < co_argcount + co_kwonlyargcount) + if more_filling: def_first = co_argcount - (0 if defaults_w is None else len(defaults_w)) j = 0 kwds_index = -1 @@ -271,6 +264,16 @@ if kwds_index >= 0: scope_w[i] = keywords_w[kwds_index] + if too_many_args: + kwonly_given = 0 + for i in range(co_argcount, co_argcount + co_kwonlyargcount): + if scope_w[i] is not None: + kwonly_given += 1 + raise ArgErrTooMany(signature.num_argnames(), + 0 if defaults_w is None else len(defaults_w), + avail, kwonly_given) + + if more_filling: # then, fill the normal arguments with defaults_w (if needed) for i in range(input_argcount, co_argcount): if scope_w[i] is not None: diff --git a/pypy/interpreter/test/test_argument.py b/pypy/interpreter/test/test_argument.py --- a/pypy/interpreter/test/test_argument.py +++ b/pypy/interpreter/test/test_argument.py @@ -634,6 +634,62 @@ else: assert 0, "did not raise" + def test_dont_count_default_arguments(self): + space = self.space + msg = space.unwrap(space.appexec([], """(): + def f1(*, c): pass + try: + f1(4) + except TypeError as e: + return str(e) + """)) + assert msg == 'f1() takes 0 positional arguments but 1 was given' + # + msg = space.unwrap(space.appexec([], """(): + def f1(*, c=8): pass + try: + f1(4) + except TypeError as e: + return str(e) + """)) + assert msg == 'f1() takes 0 positional arguments but 1 was given' + # + msg = space.unwrap(space.appexec([], """(): + def f1(a, b, *, c): pass + try: + f1(4, 5, 6) + except TypeError as e: + return str(e) + """)) + assert msg == 'f1() takes 2 positional arguments but 3 were given' + # + msg = space.unwrap(space.appexec([], """(): + def f1(*, c): pass + try: + f1(6, c=7) + except TypeError as e: + return str(e) + """)) + assert msg == 'f1() takes 0 positional arguments but 1 positional argument (and 1 keyword-only argument) were given' + # + msg = space.unwrap(space.appexec([], """(): + def f1(*, c, d=8, e=9): pass + try: + f1(6, 2, c=7, d=8) + except TypeError as e: + return str(e) + """)) + assert msg == 'f1() takes 0 positional arguments but 2 positional arguments (and 2 keyword-only arguments) were given' + # + msg = space.unwrap(space.appexec([], """(): + def f1(*, c, d=8, e=9, **kwds): pass + try: + f1(6, 2, c=7, d=8, morestuff=9) + except TypeError as e: + return str(e) + """)) + assert msg == 'f1() takes 0 positional arguments but 2 positional arguments (and 2 keyword-only arguments) were given' + def test_unknown_keywords(self): space = DummySpace() err = ArgErrUnknownKwds(space, 1, ['a', 'b'], [0], None) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit