[pypy-commit] pypy default: Make sure that the header declarations use the same types as were passed to @api_decl

rlamy pypy.commits at gmail.com
Sat Jan 21 15:07:30 EST 2017


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: 
Changeset: r89683:7075c0cf6f95
Date: 2017-01-21 20:06 +0000
http://bitbucket.org/pypy/pypy/changeset/7075c0cf6f95/

Log:	Make sure that the header declarations use the same types as were
	passed to @api_decl

diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -379,10 +379,14 @@
 
     def get_c_restype(self, c_writer):
         if self.cdecl:
-            return self.cdecl.split(self.c_name)[0].strip()
+            return self.cdecl.tp.result.get_c_name()
         return c_writer.gettype(self.restype).replace('@', '').strip()
 
     def get_c_args(self, c_writer):
+        if self.cdecl:
+            args = [tp.get_c_name('arg%d' % i) for i, tp in
+                enumerate(self.cdecl.tp.args)]
+            return ', '.join(args) or "void"
         args = []
         for i, argtype in enumerate(self.argtypes):
             if argtype is CONST_STRING:
@@ -479,14 +483,15 @@
         return unwrapper
     return decorate
 
-def api_decl(cdecl, cts, error=_NOT_SPECIFIED, header=DEFAULT_HEADER):
+def api_decl(cdef, cts, error=_NOT_SPECIFIED, header=DEFAULT_HEADER):
     def decorate(func):
         func._always_inline_ = 'try'
-        name, FUNC = cts.parse_func(cdecl)
+        cdecl = cts.parse_func(cdef)
+        RESULT = cdecl.get_llresult(cts)
         api_function = ApiFunction(
-            FUNC.ARGS, FUNC.RESULT, func,
-            error=_compute_error(error, FUNC.RESULT), cdecl=cdecl)
-        FUNCTIONS_BY_HEADER[header][name] = api_function
+            cdecl.get_llargs(cts), RESULT, func,
+            error=_compute_error(error, RESULT), cdecl=cdecl)
+        FUNCTIONS_BY_HEADER[header][cdecl.name] = api_function
         unwrapper = api_function.get_unwrapper()
         unwrapper.func = func
         unwrapper.api_func = api_function
diff --git a/pypy/module/cpyext/cparser.py b/pypy/module/cpyext/cparser.py
--- a/pypy/module/cpyext/cparser.py
+++ b/pypy/module/cpyext/cparser.py
@@ -856,8 +856,7 @@
         ast, _, _ = self.ctx._parse(cdecl)
         decl = ast.ext[-1]
         tp, quals = self.ctx._get_type_and_quals(decl.type, name=decl.name)
-        FUNCP = self.convert_type(tp.as_function_pointer())
-        return decl.name, FUNCP.TO
+        return FunctionDeclaration(decl.name, tp)
 
     def _freeze_(self):
         if self._frozen:
@@ -881,6 +880,16 @@
         self._frozen = True
         return True
 
+class FunctionDeclaration(object):
+    def __init__(self, name, tp):
+        self.name = name
+        self.tp = tp
+
+    def get_llargs(self, cts):
+        return [cts.convert_type(arg) for arg in self.tp.args]
+
+    def get_llresult(self, cts):
+        return cts.convert_type(self.tp.result)
 
 def parse_source(source, includes=None, headers=None, configure_now=True):
     cts = CTypeSpace(headers=headers, includes=includes)
diff --git a/pypy/module/cpyext/test/test_cparser.py b/pypy/module/cpyext/test/test_cparser.py
--- a/pypy/module/cpyext/test/test_cparser.py
+++ b/pypy/module/cpyext/test/test_cparser.py
@@ -185,10 +185,27 @@
     typedef TestFloatObject* (*func_t)(int, int);
     """
     cts = parse_source(decl)
-    name, FUNC = cts.parse_func("func_t some_func(TestFloatObject*)")
-    assert name == 'some_func'
-    assert FUNC.RESULT == cts.gettype('func_t')
-    assert FUNC.ARGS == (cts.gettype('TestFloatObject *'),)
+    func_decl = cts.parse_func("func_t * some_func(TestFloatObject*)")
+    assert func_decl.name == 'some_func'
+    assert func_decl.get_llresult(cts) == cts.gettype('func_t*')
+    assert func_decl.get_llargs(cts) == [cts.gettype('TestFloatObject *')]
+
+def test_write_func():
+    from ..api import ApiFunction
+    from rpython.translator.c.database import LowLevelDatabase
+    db = LowLevelDatabase()
+    cdef = """
+    typedef ssize_t Py_ssize_t;
+    """
+    cts = parse_source(cdef)
+    cdecl = "Py_ssize_t * some_func(Py_ssize_t*)"
+    decl = cts.parse_func(cdecl)
+    api_function = ApiFunction(
+        decl.get_llargs(cts), decl.get_llresult(cts), lambda space, x: None,
+        cdecl=decl)
+    assert (api_function.get_api_decl('some_func', db) ==
+            "PyAPI_FUNC(Py_ssize_t *) some_func(Py_ssize_t * arg0);")
+
 
 def test_wchar_t():
     cdef = """


More information about the pypy-commit mailing list