[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