[pypy-commit] cffi default: Test and fix (thanks Sarvi on python-cffi): there was some dependency

arigo noreply at buildbot.pypy.org
Tue Sep 11 11:46:15 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r924:d71ddeaf61ed
Date: 2012-09-11 11:46 +0200
http://bitbucket.org/cffi/cffi/changeset/d71ddeaf61ed/

Log:	Test and fix (thanks Sarvi on python-cffi): there was some
	dependency on dictionary order when half the structs were complete
	and half not.

diff --git a/cffi/vengine_cpy.py b/cffi/vengine_cpy.py
--- a/cffi/vengine_cpy.py
+++ b/cffi/vengine_cpy.py
@@ -9,6 +9,7 @@
     def __init__(self, verifier):
         self.verifier = verifier
         self.ffi = verifier.ffi
+        self._struct_pending_verification = {}
 
     def patch_extension_kwds(self, kwds):
         pass
@@ -416,7 +417,6 @@
         if tp.fldnames is None:
             return     # nothing to do with opaque structs
         layoutfuncname = '_cffi_layout_%s_%s' % (prefix, name)
-        cname = ('%s %s' % (prefix, name)).strip()
         #
         function = getattr(module, layoutfuncname)
         layout = function()
@@ -431,8 +431,16 @@
             assert len(fieldofs) == len(fieldsize) == len(tp.fldnames)
             tp.fixedlayout = fieldofs, fieldsize, totalsize, totalalignment
         else:
-            # check that the function()'s sizes and offsets match
-            # the real ones
+            cname = ('%s %s' % (prefix, name)).strip()
+            self._struct_pending_verification[tp] = layout, cname
+
+    def _loaded_struct_or_union(self, tp):
+        if tp.fldnames is None:
+            return     # nothing to do with opaque structs
+        self.ffi._get_cached_btype(tp)   # force 'fixedlayout' to be considered
+
+        if tp in self._struct_pending_verification:
+            # check that the layout sizes and offsets match the real ones
             def check(realvalue, expectedvalue, msg):
                 if realvalue != expectedvalue:
                     raise ffiplatform.VerificationError(
@@ -440,6 +448,7 @@
                         % (cname, msg, expectedvalue, realvalue))
             ffi = self.ffi
             BStruct = ffi._get_cached_btype(tp)
+            layout, cname = self._struct_pending_verification.pop(tp)
             check(layout[0], ffi.sizeof(BStruct), "wrong total size")
             check(layout[1], ffi.alignof(BStruct), "wrong total alignment")
             i = 2
@@ -454,11 +463,6 @@
                 i += 2
             assert i == len(layout)
 
-    def _loaded_struct_or_union(self, tp):
-        if tp.fldnames is None:
-            return     # nothing to do with opaque structs
-        self.ffi._get_cached_btype(tp)   # force 'fixedlayout' to be considered
-
     # ----------
     # 'anonymous' declarations.  These are produced for anonymous structs
     # or unions; the 'name' is obtained by a typedef.
diff --git a/cffi/vengine_gen.py b/cffi/vengine_gen.py
--- a/cffi/vengine_gen.py
+++ b/cffi/vengine_gen.py
@@ -10,6 +10,7 @@
         self.verifier = verifier
         self.ffi = verifier.ffi
         self.export_symbols = []
+        self._struct_pending_verification = {}
 
     def patch_extension_kwds(self, kwds):
         # add 'export_symbols' to the dictionary.  Note that we add the
@@ -232,7 +233,6 @@
         if tp.fldnames is None:
             return     # nothing to do with opaque structs
         layoutfuncname = '_cffi_layout_%s_%s' % (prefix, name)
-        cname = ('%s %s' % (prefix, name)).strip()
         #
         BFunc = self.ffi.typeof("ssize_t(*)(ssize_t)")
         function = module.load_function(BFunc, layoutfuncname)
@@ -254,8 +254,16 @@
             assert len(fieldofs) == len(fieldsize) == len(tp.fldnames)
             tp.fixedlayout = fieldofs, fieldsize, totalsize, totalalignment
         else:
-            # check that the function()'s sizes and offsets match
-            # the real ones
+            cname = ('%s %s' % (prefix, name)).strip()
+            self._struct_pending_verification[tp] = layout, cname
+
+    def _loaded_struct_or_union(self, tp):
+        if tp.fldnames is None:
+            return     # nothing to do with opaque structs
+        self.ffi._get_cached_btype(tp)   # force 'fixedlayout' to be considered
+
+        if tp in self._struct_pending_verification:
+            # check that the layout sizes and offsets match the real ones
             def check(realvalue, expectedvalue, msg):
                 if realvalue != expectedvalue:
                     raise ffiplatform.VerificationError(
@@ -263,6 +271,7 @@
                         % (cname, msg, expectedvalue, realvalue))
             ffi = self.ffi
             BStruct = ffi._get_cached_btype(tp)
+            layout, cname = self._struct_pending_verification.pop(tp)
             check(layout[0], ffi.sizeof(BStruct), "wrong total size")
             check(layout[1], ffi.alignof(BStruct), "wrong total alignment")
             i = 2
@@ -277,11 +286,6 @@
                 i += 2
             assert i == len(layout)
 
-    def _loaded_struct_or_union(self, tp):
-        if tp.fldnames is None:
-            return     # nothing to do with opaque structs
-        self.ffi._get_cached_btype(tp)   # force 'fixedlayout' to be considered
-
     # ----------
     # 'anonymous' declarations.  These are produced for anonymous structs
     # or unions; the 'name' is obtained by a typedef.
diff --git a/testing/test_verify.py b/testing/test_verify.py
--- a/testing/test_verify.py
+++ b/testing/test_verify.py
@@ -1046,3 +1046,18 @@
     lib = ffi.verify("int foo(int a) { return a + 42; }", tmpdir=tmpdir)
     assert os.listdir(tmpdir)
     assert lib.foo(100) == 142
+
+def test_bug1():
+    ffi = FFI()
+    ffi.cdef("""
+        typedef struct tdlhandle_s { ...; } *tdl_handle_t;
+        typedef struct my_error_code_ {
+            tdl_handle_t *rh;
+        } my_error_code_t;
+    """)
+    ffi.verify("""
+        typedef struct tdlhandle_s { int foo; } *tdl_handle_t;
+        typedef struct my_error_code_ {
+            tdl_handle_t *rh;
+        } my_error_code_t;
+    """)


More information about the pypy-commit mailing list