]> granicus.if.org Git - python/commitdiff
Correct handling of functions with only kwarg args in getcallargs (closes #11256)
authorBenjamin Peterson <benjamin@python.org>
Mon, 28 Mar 2011 22:32:31 +0000 (17:32 -0500)
committerBenjamin Peterson <benjamin@python.org>
Mon, 28 Mar 2011 22:32:31 +0000 (17:32 -0500)
A patch from Daniel Urban.

Lib/inspect.py
Lib/test/test_inspect.py
Misc/NEWS

index aa951d83e244b0476096ca02cfdb2d77ab92f8f2..4899cbf9f05ccfe889c43a12c36219bb4b9dc41e 100644 (file)
@@ -944,8 +944,14 @@ def getcallargs(func, *positional, **named):
             f_name, 'at most' if defaults else 'exactly', num_args,
             'arguments' if num_args > 1 else 'argument', num_total))
     elif num_args == 0 and num_total:
-        raise TypeError('%s() takes no arguments (%d given)' %
-                        (f_name, num_total))
+        if varkw or kwonlyargs:
+            if num_pos:
+                # XXX: We should use num_pos, but Python also uses num_total:
+                raise TypeError('%s() takes exactly 0 positional arguments '
+                                '(%d given)' % (f_name, num_total))
+        else:
+            raise TypeError('%s() takes no arguments (%d given)' %
+                            (f_name, num_total))
 
     for arg in itertools.chain(args, kwonlyargs):
         if arg in named:
index 331d24750019d887155a715c9b1de34bd7e894ad..7d7e16e0e15623275c5f10fa1e658072b3f2885f 100644 (file)
@@ -632,6 +632,16 @@ class TestGetcallargsFunctions(unittest.TestCase):
         self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
         self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
 
+    def test_varkw_only(self):
+        # issue11256:
+        f = self.makeCallable('**c')
+        self.assertEqualCallArgs(f, '')
+        self.assertEqualCallArgs(f, 'a=1')
+        self.assertEqualCallArgs(f, 'a=1, b=2')
+        self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
+        self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
+        self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
+
     def test_keyword_only(self):
         f = self.makeCallable('a=3, *, c, d=2')
         self.assertEqualCallArgs(f, 'c=3')
@@ -643,6 +653,11 @@ class TestGetcallargsFunctions(unittest.TestCase):
         self.assertEqualException(f, 'a=3')
         self.assertEqualException(f, 'd=4')
 
+        f = self.makeCallable('*, c, d=2')
+        self.assertEqualCallArgs(f, 'c=3')
+        self.assertEqualCallArgs(f, 'c=3, d=4')
+        self.assertEqualCallArgs(f, 'd=4, c=3')
+
     def test_multiple_features(self):
         f = self.makeCallable('a, b=2, *f, **g')
         self.assertEqualCallArgs(f, '2, 3, 7')
@@ -656,6 +671,17 @@ class TestGetcallargsFunctions(unittest.TestCase):
                                  '(4,[5,6])]), **collections.UserDict('
                                  'y=9, z=10)')
 
+        f = self.makeCallable('a, b=2, *f, x, y=99, **g')
+        self.assertEqualCallArgs(f, '2, 3, x=8')
+        self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
+        self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
+        self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
+        self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
+                                 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
+        self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
+                                 '(4,[5,6])]), q=0, **collections.UserDict('
+                                 'y=9, z=10)')
+
     def test_errors(self):
         f0 = self.makeCallable('')
         f1 = self.makeCallable('a, b')
@@ -692,6 +718,13 @@ class TestGetcallargsFunctions(unittest.TestCase):
             # - for functions and bound methods: unexpected keyword 'c'
             # - for unbound methods: multiple values for keyword 'a'
             #self.assertEqualException(f, '1, c=3, a=2')
+        # issue11256:
+        f3 = self.makeCallable('**c')
+        self.assertEqualException(f3, '1, 2')
+        self.assertEqualException(f3, '1, 2, a=1, b=2')
+        f4 = self.makeCallable('*, a, b=0')
+        self.assertEqualException(f3, '1, 2')
+        self.assertEqualException(f3, '1, 2, a=1, b=2')
 
 class TestGetcallargsMethods(TestGetcallargsFunctions):
 
index bfb9ff177b7c4b252d6c660096b14ec621dc5f8a..3f1bb3450bb8fdbe11ab41475686b54d9d825a75 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -49,6 +49,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #11256: Fix inspect.getcallargs on functions that take only keyword
+  arguments.
+
 - Issue #11696: Fix ID generation in msilib.
 
 - Issue #9696: Fix exception incorrectly raised by xdrlib.Packer.pack_int when