[pypy-commit] pypy rffi-parser-2: Make ParsedSource.configure_types() testable

rlamy pypy.commits at gmail.com
Fri Dec 23 17:45:12 EST 2016


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: rffi-parser-2
Changeset: r89216:2981e828d28d
Date: 2016-12-23 12:08 +0100
http://bitbucket.org/pypy/pypy/changeset/2981e828d28d/

Log:	Make ParsedSource.configure_types() testable

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
@@ -55,18 +55,19 @@
     udir,
     ]
 
-class CConfig:
-    _compilation_info_ = ExternalCompilationInfo(
+configure_eci = ExternalCompilationInfo(
         include_dirs=include_dirs,
         includes=['Python.h', 'stdarg.h', 'structmember.h'],
-        compile_extra=['-DPy_BUILD_CORE'],
-        )
+        compile_extra=['-DPy_BUILD_CORE'])
+
+class CConfig:
+    _compilation_info_ = configure_eci
 
 class CConfig2:
-    _compilation_info_ = CConfig._compilation_info_
+    _compilation_info_ = configure_eci
 
 class CConfig_constants:
-    _compilation_info_ = CConfig._compilation_info_
+    _compilation_info_ = configure_eci
 
 VA_LIST_P = rffi.VOIDP # rffi.COpaquePtr('va_list')
 CONST_STRING = lltype.Ptr(lltype.Array(lltype.Char,
@@ -1484,7 +1485,7 @@
         include_lines.append('RPY_EXPORTED %s %s;\n' % (typ, name))
 
     lines.append('};\n')
-    eci2 = CConfig._compilation_info_.merge(ExternalCompilationInfo(
+    eci2 = configure_eci.merge(ExternalCompilationInfo(
         separate_module_sources = [''.join(lines)],
         post_include_bits = [''.join(include_lines)],
         ))
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
@@ -670,15 +670,17 @@
 
 
 class ParsedSource(object):
-    def __init__(self, source, parser, definitions=None, macros=None):
-        from pypy.module.cpyext.api import CConfig
+    def __init__(self, source, parser, definitions=None, macros=None, eci=None):
+        from pypy.module.cpyext.api import configure_eci
         self.source = source
         self.definitions = definitions if definitions is not None else {}
         self.macros = macros if macros is not None else {}
         self.structs = {}
         self.ctx = parser
-        self._Config = type('Config', (object,), {})
-        self._Config._compilation_info_ = CConfig._compilation_info_
+        if eci is None:
+            eci = configure_eci
+        self._Config = type(
+            'Config', (object,), {'_compilation_info_': eci})
         self._TYPES = {}
 
     def add_typedef(self, name, obj):
@@ -703,7 +705,6 @@
             return DelayedStruct(obj.name, fields)
 
     def realize_struct(self, struct, type_name):
-        from pypy.module.cpyext.api import CConfig, TYPES
         configname = type_name.replace(' ', '__')
         setattr(self._Config, configname,
             rffi_platform.Struct(type_name, struct.fields))
@@ -742,14 +743,14 @@
             raise NotImplementedError
 
 
-def parse_source(source, includes=None):
+def parse_source(source, includes=None, eci=None):
     ctx = Parser()
     if includes is not None:
         for header in includes:
             ctx.include(header.ctx)
 
     ctx.parse(source)
-    src = ParsedSource(source, ctx)
+    src = ParsedSource(source, ctx, eci=eci)
     for name, (obj, quals) in ctx._declarations.iteritems():
         if obj in ctx._included_declarations:
             continue
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
@@ -1,7 +1,8 @@
-from rpython.rtyper.lltypesystem import rffi
-from pypy.module.cpyext.cparser import Parser, cname_to_lltype, parse_source
+from rpython.rtyper.lltypesystem import rffi, lltype
+from rpython.translator.tool.cbuild import ExternalCompilationInfo
+from pypy.module.cpyext.cparser import parse_source
 
-def test_stuff():
+def test_configure(tmpdir):
     decl = """
     typedef ssize_t Py_ssize_t;
 
@@ -9,14 +10,19 @@
         Py_ssize_t ob_refcnt;
         Py_ssize_t ob_pypy_link;
         double ob_fval;
-    } PyFloatObject;
+    } TestFloatObject;
     """
-    ctx = Parser()
-    ctx.parse(decl)
-    obj = ctx._declarations['typedef PyFloatObject'][0]
-    assert [cname_to_lltype(tp.name) for tp in obj.fldtypes] == [
-        rffi.SSIZE_T, rffi.SSIZE_T, rffi.DOUBLE]
-    res = parse_source(decl)
+    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)
+    res.configure_types()
+    TestFloatObject = res.definitions['TestFloatObject'].OF
+    assert isinstance(TestFloatObject, lltype.Struct)
+    assert TestFloatObject.c_ob_refcnt == rffi.SSIZE_T
+    assert TestFloatObject.c_ob_pypy_link == rffi.SSIZE_T
+    assert TestFloatObject.c_ob_fval == rffi.DOUBLE
 
 def test_simple():
     decl = "typedef ssize_t Py_ssize_t;"


More information about the pypy-commit mailing list