[pypy-commit] pypy rffi-parser-2: Add .gettype()

rlamy pypy.commits at gmail.com
Tue Dec 27 14:04:23 EST 2016


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: rffi-parser-2
Changeset: r89251:1fc5cb8950e1
Date: 2016-12-27 20:03 +0100
http://bitbucket.org/pypy/pypy/changeset/1fc5cb8950e1/

Log:	Add .gettype()

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
@@ -658,27 +658,27 @@
 
 """)
 
-Py_ssize_t = object_h.definitions['Py_ssize_t']
-Py_ssize_tP = rffi.CArrayPtr(Py_ssize_t)
+Py_ssize_t = object_h.gettype('Py_ssize_t')
+Py_ssize_tP = object_h.gettype('Py_ssize_t *')
 size_t = rffi.ULONG
 ADDR = lltype.Signed
 
 # Note: as a special case, "PyObject" is the pointer type in RPython,
 # corresponding to "PyObject *" in C.  We do that only for PyObject.
 # For example, "PyTypeObject" is the struct type even in RPython.
-PyTypeObject = object_h.definitions['PyTypeObject']
-PyTypeObjectPtr = lltype.Ptr(PyTypeObject)
-PyObjectStruct = object_h.definitions['PyObject']
-PyObject = lltype.Ptr(PyObjectStruct)
+PyTypeObject = object_h.gettype('PyTypeObject')
+PyTypeObjectPtr = object_h.gettype('PyTypeObject *')
+PyObjectStruct = object_h.gettype('PyObject')
+PyObject = object_h.gettype('PyObject *')
 PyObjectFields = (("ob_refcnt", lltype.Signed),
                   ("ob_pypy_link", lltype.Signed),
                   ("ob_type", PyTypeObjectPtr))
 PyVarObjectFields = PyObjectFields + (("ob_size", Py_ssize_t), )
-PyVarObjectStruct = object_h.definitions['PyVarObject']
-PyVarObject = lltype.Ptr(PyVarObjectStruct)
+PyVarObjectStruct = object_h.gettype('PyVarObject')
+PyVarObject = object_h.gettype('PyVarObject *')
 
-Py_buffer = object_h.definitions['Py_buffer']
-Py_bufferP = lltype.Ptr(Py_buffer)
+Py_buffer = object_h.gettype('Py_buffer')
+Py_bufferP = object_h.gettype('Py_buffer *')
 
 
 @specialize.memo()
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
@@ -284,8 +284,7 @@
         return self.parse_type_and_quals(cdecl)[0]
 
     def parse_type_and_quals(self, cdecl):
-        ast, macros = self._parse('void __dummy(\n%s\n);' % cdecl)[:2]
-        assert not macros
+        ast, _, _ = self._parse('void __dummy(\n%s\n);' % cdecl)
         exprnode = ast.ext[-1].type.args.params[0]
         if isinstance(exprnode, pycparser.c_ast.ID):
             raise api.CDefError("unknown identifier '%s'" % (exprnode.name,))
@@ -777,6 +776,13 @@
         else:
             raise NotImplementedError
 
+    def gettype(self, cdecl):
+        obj = self.ctx.parse_type(cdecl)
+        result = self.convert_type(obj)
+        if isinstance(result, DelayedStruct):
+            result = result.TYPE
+        return result
+
 
 def parse_source(source, includes=None, eci=None, configure_now=False):
     ctx = Parser()
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
@@ -99,7 +99,7 @@
         include_dirs=[str(tmpdir)],
         includes=['sys/types.h', 'foo.h'])
     foo_h = parse_source(cdef, eci=eci)
-    Object = foo_h.definitions['Object']
+    Object = foo_h.gettype('Object')
     assert isinstance(Object, lltype.ForwardReference)
 
 def test_recursive(tmpdir):
@@ -142,3 +142,24 @@
         includes=['sys/types.h', 'foo.h'])
     hdr = parse_source(cdef, eci=eci, configure_now=True)
     assert hdr.definitions['bar'].c_foo == rffi.CONST_CCHARP != rffi.CCHARP
+
+def test_gettype(tmpdir):
+    decl = """
+    typedef ssize_t Py_ssize_t;
+
+    #define PyObject_HEAD  \
+        Py_ssize_t ob_refcnt;        \
+        Py_ssize_t ob_pypy_link;     \
+
+    typedef struct {
+        PyObject_HEAD
+        double ob_fval;
+    } TestFloatObject;
+    """
+    hdr = tmpdir / 'header.h'
+    hdr.write(decl)
+    eci = ExternalCompilationInfo(
+        include_dirs=[str(tmpdir)], includes=['sys/types.h', 'header.h'])
+    res = parse_source(decl, eci=eci, configure_now=True)
+    assert res.gettype('Py_ssize_t') == rffi.SSIZE_T
+    assert res.gettype('TestFloatObject *').TO.c_ob_refcnt == rffi.SSIZE_T


More information about the pypy-commit mailing list