some code cleanup and beautification, fix error message to match Python when passing...
authorStefan Behnel <scoder@users.berlios.de>
Mon, 25 Aug 2008 13:37:37 +0000 (15:37 +0200)
committerStefan Behnel <scoder@users.berlios.de>
Mon, 25 Aug 2008 13:37:37 +0000 (15:37 +0200)
Cython/Compiler/Nodes.py
tests/run/kwonlyargscall.pyx

index d3596ea21daee478ba6c0b042ae2f6084bb9472f..08c8c4ea4a10f91ffee8e682052adf5dec800857 100644 (file)
@@ -1753,10 +1753,10 @@ class DefNode(FuncDefNode):
         if self.star_arg:
             code.putln('default:')
         for i in range(max_positional_args-1, -1, -1):
-            code.putln('case %d:' % (i+1))
+            code.put('case %2d: ' % (i+1))
             code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
                     i, Naming.args_cname, i))
-        code.putln('case 0: break;')
+        code.putln('case  0: break;')
         if not self.star_arg:
             code.put('default: ') # more arguments than allowed
             code.put_goto(argtuple_error_label)
@@ -1769,7 +1769,7 @@ class DefNode(FuncDefNode):
                 if self.star_arg and i == max_positional_args:
                     code.putln('default:')
                 else:
-                    code.putln('case %d:' % i)
+                    code.putln('case %2d:' % i)
             code.putln('values[%d] = PyDict_GetItem(%s, *%s[%d]);' % (
                     i, Naming.kwds_cname, Naming.pykwdlist_cname, i))
             if i < min_positional_args:
@@ -1828,11 +1828,11 @@ class DefNode(FuncDefNode):
 
         if self.num_required_kw_args:
             # pure error case: keywords required but not passed
+            if max_positional_args > min_positional_args and not self.star_arg:
+                code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
+                        Naming.args_cname, max_positional_args))
+                code.put_goto(argtuple_error_label)
             code.putln('} else {')
-            if not self.star_arg and not self.starstar_arg:
-                # optional args missing?
-                self.generate_positional_args_check(
-                    max_positional_args, has_fixed_positional_count, code)
             for i, arg in enumerate(kw_only_args):
                 if not arg.default:
                     # required keyword-only argument missing
@@ -1856,12 +1856,15 @@ class DefNode(FuncDefNode):
             reversed_args = list(enumerate(positional_args))[::-1]
             for i, arg in reversed_args:
                 if i >= min_positional_args-1:
-                    code.putln('case %d:' % (i+1))
+                    if min_positional_args > 1:
+                        code.putln('case %2d:' % (i+1)) # pure code beautification
+                    else:
+                        code.put('case %2d: ' % (i+1))
                 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
                 self.generate_arg_assignment(arg, item, code)
             if not self.star_arg:
                 if min_positional_args == 0:
-                    code.putln('case 0:')
+                    code.put('case  0: ')
                 code.putln('break;')
                 code.put('default: ')
                 code.put_goto(argtuple_error_label)
index 22fa29a6f9ccf790b4477e962e9a414d17f87df6..f05473e83256fdd37ed5ffd756e2e432d98897a8 100644 (file)
@@ -114,6 +114,21 @@ __doc__ = u"""
     >>> call2d(k)
     Traceback (most recent call last):
     TypeError: k() needs keyword-only argument f
+
+    >>> call0abc(m)
+    1 2 3
+    >>> call2c(m)
+    1 2 1
+
+    >>> call3(m)
+    Traceback (most recent call last):
+    TypeError: m() takes at most 2 positional arguments (3 given)
+    >>> call2(m)
+    Traceback (most recent call last):
+    TypeError: m() needs keyword-only argument c
+    >>> call2cd(m)
+    Traceback (most recent call last):
+    TypeError: 'd' is an invalid keyword argument for this function
 """
 
 # the calls:
@@ -212,3 +227,6 @@ def k(a, b, c=1, *args, d = 42, e = 17, f, **kwds):
     kwlist = list(kwds.items())
     kwlist.sort()
     print a,b,c,d,e,f, args, kwlist
+
+def m(a, b=1, *, c):
+    print a,b,c