Author: Ronan Lamy <ronan.l...@gmail.com> Branch: rffi-parser-2 Changeset: r89544:bdd3e262b996 Date: 2017-01-13 16:13 +0000 http://bitbucket.org/pypy/pypy/changeset/bdd3e262b996/
Log: Configure types using only the C source passed to parse_source() 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 @@ -974,7 +974,7 @@ } PyTypeObject; -""", configure_now=True) +""", headers=['sys/types.h', 'stdarg.h', 'stdio.h'], configure_now=True) Py_ssize_t = object_h.gettype('Py_ssize_t') Py_ssize_tP = object_h.gettype('Py_ssize_t *') 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 @@ -6,6 +6,7 @@ except ImportError: import pycparser import weakref, re +from rpython.translator.tool.cbuild import ExternalCompilationInfo from rpython.rlib.rfile import FILEP from rpython.rtyper.lltypesystem import rffi, lltype from rpython.rtyper.tool import rfficache, rffi_platform @@ -675,17 +676,15 @@ class ParsedSource(object): - def __init__(self, source, parser, definitions=None, macros=None, eci=None): + def __init__(self, source, parser, definitions=None, macros=None, headers=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 - if eci is None: - eci = configure_eci - self._Config = type( - 'Config', (object,), {'_compilation_info_': eci}) + self.headers = headers if headers is not None else ['sys/types.h'] + self._Config = type('Config', (object,), {}) self._TYPES = {} self.includes = [] @@ -728,6 +727,16 @@ cpython_struct(type_name, struct.fields, forward=struct.TYPE) return struct.TYPE + def build_eci(self): + all_sources = [x.source for x in self.includes] + [self.source] + all_headers = self.headers + for x in self.includes: + for hdr in x.headers: + if hdr not in all_headers: + all_headers.append(hdr) + return ExternalCompilationInfo( + post_include_bits=all_sources, includes=all_headers) + def configure_types(self, configure_now=False): for name, (obj, quals) in self.ctx._declarations.iteritems(): if obj in self.ctx._included_declarations: @@ -738,6 +747,7 @@ elif name.startswith('macro '): name = name[6:] self.add_macro(name, obj) + self._Config._compilation_info_ = self.build_eci() for name, TYPE in rffi_platform.configure(self._Config).iteritems(): if name in self._TYPES: self._TYPES[name].become(TYPE) @@ -794,9 +804,9 @@ return decl.name, FUNCP.TO -def parse_source(source, includes=None, eci=None, configure_now=False): +def parse_source(source, includes=None, headers=None, configure_now=False): ctx = Parser() - src = ParsedSource(source, ctx, eci=eci) + src = ParsedSource(source, ctx, headers=headers) if includes is not None: for header in includes: src.include(header) 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,8 +1,7 @@ from rpython.rtyper.lltypesystem import rffi, lltype -from rpython.translator.tool.cbuild import ExternalCompilationInfo from pypy.module.cpyext.cparser import parse_source -def test_configure(tmpdir): +def test_configure(): decl = """ typedef ssize_t Py_ssize_t; @@ -12,11 +11,7 @@ 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) + res = parse_source(decl, configure_now=True) TestFloatObject = res.definitions['TestFloatObject'] assert isinstance(TestFloatObject, lltype.Struct) assert TestFloatObject.c_ob_refcnt == rffi.SSIZE_T @@ -45,7 +40,7 @@ assert 'PyFloatObject' in hdr.definitions assert 'PyObject_HEAD' in hdr.macros -def test_include(tmpdir): +def test_include(): cdef1 = """ typedef ssize_t Py_ssize_t; @@ -57,8 +52,6 @@ char *name; } Type; """ - base_name = tmpdir / 'base.h' - base_name.write(cdef1) cdef2 = """ typedef struct { PyObject_HEAD @@ -66,19 +59,15 @@ Type *type; } Object; """ - (tmpdir / 'object.h').write(cdef2) - eci = ExternalCompilationInfo( - include_dirs=[str(tmpdir)], - includes=['sys/types.h', 'base.h', 'object.h']) - hdr1 = parse_source(cdef1, eci=eci, configure_now=True) + hdr1 = parse_source(cdef1, configure_now=True) Type = hdr1.definitions['Type'] assert isinstance(Type, lltype.Struct) - hdr2 = parse_source(cdef2, includes=[hdr1], eci=eci, configure_now=True) + hdr2 = parse_source(cdef2, includes=[hdr1], configure_now=True) assert 'Type' not in hdr2.definitions Object = hdr2.definitions['Object'] assert Object.c_type.TO is Type -def test_incomplete(tmpdir): +def test_incomplete(): cdef = """ typedef ssize_t Py_ssize_t; @@ -94,15 +83,11 @@ } Buffer; """ - (tmpdir / 'foo.h').write(cdef) - eci = ExternalCompilationInfo( - include_dirs=[str(tmpdir)], - includes=['sys/types.h', 'foo.h']) - foo_h = parse_source(cdef, eci=eci) + foo_h = parse_source(cdef) Object = foo_h.gettype('Object') assert isinstance(Object, lltype.ForwardReference) -def test_recursive(tmpdir): +def test_recursive(): cdef = """ typedef ssize_t Py_ssize_t; @@ -121,29 +106,21 @@ Object *obj; } Type; """ - (tmpdir / 'foo.h').write(cdef) - eci = ExternalCompilationInfo( - include_dirs=[str(tmpdir)], - includes=['sys/types.h', 'foo.h']) - foo_h = parse_source(cdef, eci=eci, configure_now=True) + foo_h = parse_source(cdef, configure_now=True) Object = foo_h.definitions['Object'] assert isinstance(Object, lltype.Struct) hash(Object) -def test_const(tmpdir): +def test_const(): cdef = """ typedef struct { const char * const foo; } bar; """ - (tmpdir / 'foo.h').write(cdef) - eci = ExternalCompilationInfo( - include_dirs=[str(tmpdir)], - includes=['sys/types.h', 'foo.h']) - hdr = parse_source(cdef, eci=eci, configure_now=True) + hdr = parse_source(cdef, configure_now=True) assert hdr.definitions['bar'].c_foo == rffi.CONST_CCHARP != rffi.CCHARP -def test_gettype(tmpdir): +def test_gettype(): decl = """ typedef ssize_t Py_ssize_t; @@ -156,15 +133,11 @@ 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) + res = parse_source(decl, configure_now=True) assert res.gettype('Py_ssize_t') == rffi.SSIZE_T assert res.gettype('TestFloatObject *').TO.c_ob_refcnt == rffi.SSIZE_T -def test_parse_funcdecl(tmpdir): +def test_parse_funcdecl(): decl = """ typedef ssize_t Py_ssize_t; @@ -179,11 +152,7 @@ typedef TestFloatObject* (*func_t)(int, int); """ - 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) + res = parse_source(decl, configure_now=True) name, FUNC = res.parse_func("func_t some_func(TestFloatObject*)") assert name == 'some_func' assert FUNC.RESULT == res.gettype('func_t') _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit