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

Reply via email to