support keyword arguments for C function pointers
authorStefan Behnel <stefan_ml@behnel.de>
Fri, 8 Feb 2013 07:26:22 +0000 (08:26 +0100)
committerStefan Behnel <stefan_ml@behnel.de>
Fri, 8 Feb 2013 07:26:22 +0000 (08:26 +0100)
Cython/Compiler/ExprNodes.py
tests/run/cdef_function_kwargs.pyx

index 895d44f..96ff69e 100755 (executable)
@@ -4388,12 +4388,17 @@ class GeneralCallNode(CallNode):
             return self
         function = self.function
         entry = getattr(function, 'entry', None)
-        if not entry or not entry.is_cfunction:
+        if not entry:
+            return self
+        function_type = entry.type
+        if function_type.is_ptr:
+            function_type = function_type.base_type
+        if not function_type.is_cfunction:
             return self
 
         pos_args = self.positional_args.args
         kwargs = self.keyword_args
-        declared_args = entry.type.args
+        declared_args = function_type.args
         if entry.is_cmethod:
             declared_args = declared_args[1:] # skip 'self'
 
index c9c0449..b45cd8b 100644 (file)
@@ -11,6 +11,13 @@ cpdef cpfunc(a,b,c,d):
 cdef optargs(a, b=2, c=3):
     return (a,b,c)
 
+ctypedef int (*cfuncptr_type)(int a, int b)
+cdef int cfuncptr(int a, int b):
+    print a, b
+
+cdef cfuncptr_type get_cfuncptr():
+    return cfuncptr
+
 
 sideeffect = []
 cdef side_effect(x):
@@ -156,3 +163,20 @@ def cdef_optargs():
     print(optargs(b=12, a=11, c=13))
     print(optargs(b=12, c=13, a=11))
     print(optargs(c=13, a=11, b=12))
+
+
+@cython.test_fail_if_path_exists('//GeneralCallNode')
+@cython.test_assert_path_exists('//SimpleCallNode')
+def cdef_funcptr():
+    """
+    >>> cdef_funcptr()
+    1 2
+    1 2
+    1 2
+    1 2
+    """
+    cdef cfuncptr_type cfunc_ptr = get_cfuncptr()
+    cfunc_ptr(1, 2)
+    cfunc_ptr(1, b=2)
+    cfunc_ptr(a=1, b=2)
+    cfunc_ptr(b=2, a=1)