Author: Armin Rigo <ar...@tunes.org>
Branch: 
Changeset: r75847:2b94f0f584a7
Date: 2015-02-13 10:45 +0100
http://bitbucket.org/pypy/pypy/changeset/2b94f0f584a7/

Log:    pypy/tool/import_cffi.py

diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py
--- a/lib_pypy/cffi/__init__.py
+++ b/lib_pypy/cffi/__init__.py
@@ -5,7 +5,7 @@
 from .ffiplatform import VerificationError, VerificationMissing
 
 __version__ = "0.8.6+"
-__version_info__ = (0, 8, 6)
+__version_info__ = (0, 8, 6, "plus")
 
 # The verifier module file names are based on the CRC32 of a string that
 # contains the following version number.  It may be older than __version__
diff --git a/lib_pypy/cffi/api.py b/lib_pypy/cffi/api.py
--- a/lib_pypy/cffi/api.py
+++ b/lib_pypy/cffi/api.py
@@ -56,7 +56,7 @@
             import _cffi_backend as backend
             from . import __version__
             assert backend.__version__ == __version__, \
-                "version mismatch, %s != %s" % (backend.__version__, 
__version__)
+               "version mismatch, %s != %s" % (backend.__version__, 
__version__)
             # (If you insist you can also try to pass the option
             # 'backend=backend_ctypes.CTypesBackend()', but don't
             # rely on it!  It's probably not going to work well.)
diff --git a/lib_pypy/cffi/backend_ctypes.py b/lib_pypy/cffi/backend_ctypes.py
--- a/lib_pypy/cffi/backend_ctypes.py
+++ b/lib_pypy/cffi/backend_ctypes.py
@@ -2,11 +2,10 @@
 from . import model
 
 if sys.version_info < (3,):
-    integer_types = (int, long)
     bytechr = chr
 else:
     unicode = str
-    integer_types = int
+    long = int
     xrange = range
     bytechr = lambda num: bytes([num])
 
@@ -181,7 +180,7 @@
             address = 0
         elif isinstance(source, CTypesData):
             address = source._cast_to_integer()
-        elif isinstance(source, integer_types):
+        elif isinstance(source, (int, long)):
             address = source
         else:
             raise TypeError("bad type for cast to %r: %r" %
@@ -358,7 +357,7 @@
             is_signed = (ctype(-1).value == -1)
         #
         def _cast_source_to_int(source):
-            if isinstance(source, (integer_types, float)):
+            if isinstance(source, (int, long, float)):
                 source = int(source)
             elif isinstance(source, CTypesData):
                 source = source._cast_to_integer()
@@ -399,7 +398,7 @@
             if kind == 'bool':
                 @classmethod
                 def _cast_from(cls, source):
-                    if not isinstance(source, (integer_types, float)):
+                    if not isinstance(source, (int, long, float)):
                         source = _cast_source_to_int(source)
                     return cls(bool(source))
                 def __int__(self):
@@ -438,7 +437,7 @@
             if kind == 'int' or kind == 'byte' or kind == 'bool':
                 @staticmethod
                 def _to_ctypes(x):
-                    if not isinstance(x, integer_types):
+                    if not isinstance(x, (int, long)):
                         if isinstance(x, CTypesData):
                             x = int(x)
                         else:
@@ -465,7 +464,7 @@
             if kind == 'float':
                 @staticmethod
                 def _to_ctypes(x):
-                    if not isinstance(x, (integer_types, float, CTypesData)):
+                    if not isinstance(x, (int, long, float, CTypesData)):
                         raise TypeError("float expected, got %s" %
                                         type(x).__name__)
                     return ctype(x).value
@@ -529,14 +528,14 @@
                 self._own = True
 
             def __add__(self, other):
-                if isinstance(other, integer_types):
+                if isinstance(other, (int, long)):
                     return self._new_pointer_at(self._address +
                                                 other * self._bitem_size)
                 else:
                     return NotImplemented
 
             def __sub__(self, other):
-                if isinstance(other, integer_types):
+                if isinstance(other, (int, long)):
                     return self._new_pointer_at(self._address -
                                                 other * self._bitem_size)
                 elif type(self) is type(other):
@@ -611,7 +610,7 @@
 
             def __init__(self, init):
                 if length is None:
-                    if isinstance(init, integer_types):
+                    if isinstance(init, (int, long)):
                         len1 = init
                         init = None
                     elif kind == 'char' and isinstance(init, bytes):
@@ -686,7 +685,7 @@
                 return CTypesPtr._arg_to_ctypes(value)
 
             def __add__(self, other):
-                if isinstance(other, integer_types):
+                if isinstance(other, (int, long)):
                     return CTypesPtr._new_pointer_at(
                         ctypes.addressof(self._blob) +
                         other * ctypes.sizeof(BItem._ctype))
diff --git a/lib_pypy/cffi/verifier.py b/lib_pypy/cffi/verifier.py
--- a/lib_pypy/cffi/verifier.py
+++ b/lib_pypy/cffi/verifier.py
@@ -1,4 +1,4 @@
-import sys, os, binascii, shutil
+import sys, os, binascii, shutil, io
 from . import __version_verifier_modules__
 from . import ffiplatform
 
@@ -13,6 +13,16 @@
                 if type == imp.C_EXTENSION]
 
 
+if sys.version_info >= (3,):
+    NativeIO = io.StringIO
+else:
+    class NativeIO(io.BytesIO):
+        def write(self, s):
+            if isinstance(s, unicode):
+                s = s.encode('ascii')
+            super(NativeIO, self).write(s)
+
+
 class Verifier(object):
 
     def __init__(self, ffi, preamble, tmpdir=None, modulename=None,
@@ -144,19 +154,36 @@
         self._vengine.collect_types()
         self._has_module = True
 
-    def _write_source(self, file=None):
-        must_close = (file is None)
-        if must_close:
-            _ensure_dir(self.sourcefilename)
-            file = open(self.sourcefilename, 'w')
+    def _write_source_to(self, file):
         self._vengine._f = file
         try:
             self._vengine.write_source_to_f()
         finally:
             del self._vengine._f
-            if must_close:
-                file.close()
-        if must_close:
+
+    def _write_source(self, file=None):
+        if file is not None:
+            self._write_source_to(file)
+        else:
+            # Write our source file to an in memory file.
+            f = NativeIO()
+            self._write_source_to(f)
+            source_data = f.getvalue()
+
+            # Determine if this matches the current file
+            if os.path.exists(self.sourcefilename):
+                with open(self.sourcefilename, "r") as fp:
+                    needs_written = not (fp.read() == source_data)
+            else:
+                needs_written = True
+
+            # Actually write the file out if it doesn't match
+            if needs_written:
+                _ensure_dir(self.sourcefilename)
+                with open(self.sourcefilename, "w") as fp:
+                    fp.write(source_data)
+
+            # Set this flag
             self._has_source = True
 
     def _compile_module(self):
diff --git a/pypy/module/test_lib_pypy/cffi_tests/test_ownlib.py 
b/pypy/module/test_lib_pypy/cffi_tests/test_ownlib.py
--- a/pypy/module/test_lib_pypy/cffi_tests/test_ownlib.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/test_ownlib.py
@@ -8,34 +8,137 @@
 SOURCE = """\
 #include <errno.h>
 
-int test_getting_errno(void) {
+#ifdef _WIN32
+#define EXPORT __declspec(dllexport)
+#else
+#define EXPORT
+#endif
+
+EXPORT int test_getting_errno(void) {
     errno = 123;
     return -1;
 }
 
-int test_setting_errno(void) {
+EXPORT int test_setting_errno(void) {
     return errno;
+};
+
+typedef struct {
+    long x;
+    long y;
+} POINT;
+
+typedef struct {
+    long left;
+    long top;
+    long right;
+    long bottom;
+} RECT;
+
+
+EXPORT int PointInRect(RECT *prc, POINT pt)
+{
+    if (pt.x < prc->left)
+        return 0;
+    if (pt.x > prc->right)
+        return 0;
+    if (pt.y < prc->top)
+        return 0;
+    if (pt.y > prc->bottom)
+        return 0;
+    return 1;
+};
+
+EXPORT long left = 10;
+EXPORT long top = 20;
+EXPORT long right = 30;
+EXPORT long bottom = 40;
+
+EXPORT RECT ReturnRect(int i, RECT ar, RECT* br, POINT cp, RECT dr,
+                        RECT *er, POINT fp, RECT gr)
+{
+    /*Check input */
+    if (ar.left + br->left + dr.left + er->left + gr.left != left * 5)
+    {
+        ar.left = 100;
+        return ar;
+    }
+    if (ar.right + br->right + dr.right + er->right + gr.right != right * 5)
+    {
+        ar.right = 100;
+        return ar;
+    }
+    if (cp.x != fp.x)
+    {
+        ar.left = -100;
+    }
+    if (cp.y != fp.y)
+    {
+        ar.left = -200;
+    }
+    switch(i)
+    {
+    case 0:
+        return ar;
+        break;
+    case 1:
+        return dr;
+        break;
+    case 2:
+        return gr;
+        break;
+
+    }
+    return ar;
 }
 
-int my_array[7] = {0, 1, 2, 3, 4, 5, 6};
+EXPORT int my_array[7] = {0, 1, 2, 3, 4, 5, 6};
 """
 
 class TestOwnLib(object):
     Backend = CTypesBackend
 
     def setup_class(cls):
-        if sys.platform == 'win32':
-            return
+        cls.module = None
         from pypy.module.test_lib_pypy.cffi_tests.udir import udir
         udir.join('testownlib.c').write(SOURCE)
-        subprocess.check_call(
-            'gcc testownlib.c -shared -fPIC -o testownlib.so',
-            cwd=str(udir), shell=True)
-        cls.module = str(udir.join('testownlib.so'))
+        if sys.platform == 'win32':
+            import os
+            # did we already build it?
+            if os.path.exists(str(udir.join('testownlib.dll'))):
+                cls.module = str(udir.join('testownlib.dll'))
+                return
+            # try (not too hard) to find the version used to compile this 
python
+            # no mingw
+            from distutils.msvc9compiler import get_build_version
+            version = get_build_version()
+            toolskey = "VS%0.f0COMNTOOLS" % version
+            toolsdir = os.environ.get(toolskey, None)
+            if toolsdir is None:
+                return
+            productdir = os.path.join(toolsdir, os.pardir, os.pardir, "VC")
+            productdir = os.path.abspath(productdir)
+            vcvarsall = os.path.join(productdir, "vcvarsall.bat")
+            # 64?
+            arch = 'x86'
+            if sys.maxsize > 2**32:
+                arch = 'amd64'
+            if os.path.isfile(vcvarsall):
+                cmd = '"%s" %s' % (vcvarsall, arch) + ' & cl.exe testownlib.c 
' \
+                        ' /LD /Fetestownlib.dll'
+                subprocess.check_call(cmd, cwd = str(udir), shell=True)    
+                cls.module = str(udir.join('testownlib.dll'))
+        else:
+            subprocess.check_call(
+                'gcc testownlib.c -shared -fPIC -o testownlib.so',
+                cwd=str(udir), shell=True)
+            cls.module = str(udir.join('testownlib.so'))
 
     def test_getting_errno(self):
+        if self.module is None:
+            py.test.skip("fix the auto-generation of the tiny test lib")
         if sys.platform == 'win32':
-            py.test.skip("fix the auto-generation of the tiny test lib")
+            py.test.skip("fails, errno at multiple addresses")
         ffi = FFI(backend=self.Backend())
         ffi.cdef("""
             int test_getting_errno(void);
@@ -46,8 +149,10 @@
         assert ffi.errno == 123
 
     def test_setting_errno(self):
+        if self.module is None:
+            py.test.skip("fix the auto-generation of the tiny test lib")
         if sys.platform == 'win32':
-            py.test.skip("fix the auto-generation of the tiny test lib")
+            py.test.skip("fails, errno at multiple addresses")
         if self.Backend is CTypesBackend and '__pypy__' in sys.modules:
             py.test.skip("XXX errno issue with ctypes on pypy?")
         ffi = FFI(backend=self.Backend())
@@ -61,7 +166,7 @@
         assert ffi.errno == 42
 
     def test_my_array_7(self):
-        if sys.platform == 'win32':
+        if self.module is None:
             py.test.skip("fix the auto-generation of the tiny test lib")
         ffi = FFI(backend=self.Backend())
         ffi.cdef("""
@@ -81,7 +186,7 @@
             assert ownlib.my_array[i] == i
 
     def test_my_array_no_length(self):
-        if sys.platform == 'win32':
+        if self.module is None:
             py.test.skip("fix the auto-generation of the tiny test lib")
         if self.Backend is CTypesBackend:
             py.test.skip("not supported by the ctypes backend")
@@ -101,7 +206,7 @@
             assert ownlib.my_array[i] == i
 
     def test_keepalive_lib(self):
-        if sys.platform == 'win32':
+        if self.module is None:
             py.test.skip("fix the auto-generation of the tiny test lib")
         ffi = FFI(backend=self.Backend())
         ffi.cdef("""
@@ -119,7 +224,7 @@
         assert res == -1
 
     def test_keepalive_ffi(self):
-        if sys.platform == 'win32':
+        if self.module is None:
             py.test.skip("fix the auto-generation of the tiny test lib")
         ffi = FFI(backend=self.Backend())
         ffi.cdef("""
@@ -135,4 +240,46 @@
         assert ownlib_r() is not None # kept alive by ffi
         res = func()
         assert res == -1
-        assert ffi.errno == 123
+        if sys.platform != 'win32':  # else, errno at multiple addresses
+            assert ffi.errno == 123
+
+    def test_struct_by_value(self):
+        if self.module is None:
+            py.test.skip("fix the auto-generation of the tiny test lib")
+        ffi = FFI(backend=self.Backend())
+        ffi.cdef("""
+            typedef struct {
+                long x;
+                long y;
+            } POINT;
+
+            typedef struct {
+                long left;
+                long top;
+                long right;
+                long bottom;
+            } RECT;
+            
+            long left, top, right, bottom;
+
+            RECT ReturnRect(int i, RECT ar, RECT* br, POINT cp, RECT dr,
+                        RECT *er, POINT fp, RECT gr);
+        """)
+        ownlib = ffi.dlopen(self.module)
+
+        rect = ffi.new('RECT[1]')
+        pt = ffi.new('POINT[1]')
+        pt[0].x = 15
+        pt[0].y = 25
+        rect[0].left = ownlib.left
+        rect[0].right = ownlib.right
+        rect[0].top = ownlib.top
+        rect[0].bottom = ownlib.bottom
+        
+        for i in range(4):
+            ret = ownlib.ReturnRect(i, rect[0], rect, pt[0], rect[0],
+                                    rect, pt[0], rect[0])
+            assert ret.left == ownlib.left
+            assert ret.right == ownlib.right
+            assert ret.top == ownlib.top
+            assert ret.bottom == ownlib.bottom
diff --git a/pypy/module/test_lib_pypy/cffi_tests/test_verify.py 
b/pypy/module/test_lib_pypy/cffi_tests/test_verify.py
--- a/pypy/module/test_lib_pypy/cffi_tests/test_verify.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/test_verify.py
@@ -1368,7 +1368,7 @@
     ffi = FFI()
     ffi.cdef("int foo(int);")
     f = open(os.path.join(tmpdir, 'foo.h'), 'w')
-    print >> f, "int foo(int a) { return a + 42; }"
+    f.write("int foo(int a) { return a + 42; }\n")
     f.close()
     lib = ffi.verify('#include "foo.h"',
                      include_dirs=['.'],
@@ -2129,7 +2129,7 @@
         n = lib.GetModuleFileName(ffi.NULL, outbuf, 500)
         assert 0 < n < 500
         for i in range(n):
-            print repr(outbuf[i])
+            #print repr(outbuf[i])
             assert ord(outbuf[i]) != 0
         assert ord(outbuf[n]) == 0
         assert ord(outbuf[0]) < 128     # should be a letter, or '\'
diff --git a/pypy/module/test_lib_pypy/cffi_tests/test_version.py 
b/pypy/module/test_lib_pypy/cffi_tests/test_version.py
--- a/pypy/module/test_lib_pypy/cffi_tests/test_version.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/test_version.py
@@ -17,6 +17,7 @@
 def test_version():
     v = cffi.__version__
     version_info = '.'.join(str(i) for i in cffi.__version_info__)
+    version_info = version_info.replace('.plus', '+')
     assert v == version_info
     #v = BACKEND_VERSIONS.get(v, v)
     assert v == _cffi_backend.__version__
@@ -32,7 +33,7 @@
 
 def test_doc_version_file():
     parent = os.path.dirname(os.path.dirname(__file__))
-    v = cffi.__version__
+    v = cffi.__version__.replace('+', '')
     p = os.path.join(parent, 'doc', 'source', 'index.rst')
     content = open(p).read()
     assert ("cffi/cffi-%s.tar.gz" % v) in content
@@ -42,7 +43,7 @@
     p = os.path.join(parent, 'setup.py')
     content = open(p).read()
     #
-    v = cffi.__version__
+    v = cffi.__version__.replace('+', '')
     assert ("version='%s'" % v) in content
 
 def test_c_version():
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to