[pypy-commit] cffi release-1.11: hg merge default

arigo pypy.commits at gmail.com
Wed Sep 27 06:51:14 EDT 2017


Author: Armin Rigo <arigo at tunes.org>
Branch: release-1.11
Changeset: r3028:8adcf995d67c
Date: 2017-09-27 12:50 +0200
http://bitbucket.org/cffi/cffi/changeset/8adcf995d67c/

Log:	hg merge default

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -2,7 +2,7 @@
 #include <Python.h>
 #include "structmember.h"
 
-#define CFFI_VERSION  "1.11.0"
+#define CFFI_VERSION  "1.11.1"
 
 #ifdef MS_WIN32
 #include <windows.h>
@@ -101,7 +101,11 @@
 # define PyText_FromFormat PyUnicode_FromFormat
 # define PyText_AsUTF8 _PyUnicode_AsString   /* PyUnicode_AsUTF8 in Py3.3 */
 # define PyText_AS_UTF8 _PyUnicode_AsString
-# define PyText_GetSize PyUnicode_GetSize
+# if PY_VERSION_HEX >= 0x03030000
+#  define PyText_GetSize PyUnicode_GetLength
+# else
+#  define PyText_GetSize PyUnicode_GetSize
+# endif
 # define PyText_FromString PyUnicode_FromString
 # define PyText_FromStringAndSize PyUnicode_FromStringAndSize
 # define PyText_InternInPlace PyUnicode_InternInPlace
@@ -2671,7 +2675,7 @@
 static void
 _cdata_attr_errmsg(char *errmsg, CDataObject *cd, PyObject *attr)
 {
-    char *text;
+    const char *text;
     if (!PyErr_ExceptionMatches(PyExc_AttributeError))
         return;
     PyErr_Clear();
@@ -5896,7 +5900,7 @@
         if (!PyText_Check(tmpkey)) {
 #if PY_MAJOR_VERSION < 3
             if (PyUnicode_Check(tmpkey)) {
-                char *text = PyText_AsUTF8(tmpkey);
+                const char *text = PyText_AsUTF8(tmpkey);
                 if (text == NULL)
                     goto error;
                 Py_DECREF(tmpkey);
diff --git a/c/call_python.c b/c/call_python.c
--- a/c/call_python.c
+++ b/c/call_python.c
@@ -51,7 +51,7 @@
 
 static PyObject *_ffi_def_extern_decorator(PyObject *outer_args, PyObject *fn)
 {
-    char *s;
+    const char *s;
     PyObject *error, *onerror, *infotuple, *old1;
     int index, err;
     const struct _cffi_global_s *g;
diff --git a/c/cdlopen.c b/c/cdlopen.c
--- a/c/cdlopen.c
+++ b/c/cdlopen.c
@@ -1,6 +1,7 @@
 /* ffi.dlopen() interface with dlopen()/dlsym()/dlclose() */
 
-static void *cdlopen_fetch(PyObject *libname, void *libhandle, char *symbol)
+static void *cdlopen_fetch(PyObject *libname, void *libhandle,
+                           const char *symbol)
 {
     void *address;
 
diff --git a/c/ffi_obj.c b/c/ffi_obj.c
--- a/c/ffi_obj.c
+++ b/c/ffi_obj.c
@@ -92,7 +92,7 @@
 /* forward, declared in cdlopen.c because it's mostly useful for this case */
 static int ffiobj_init(PyObject *self, PyObject *args, PyObject *kwds);
 
-static PyObject *ffi_fetch_int_constant(FFIObject *ffi, char *name,
+static PyObject *ffi_fetch_int_constant(FFIObject *ffi, const char *name,
                                         int recursion)
 {
     int index;
@@ -145,7 +145,7 @@
 #define ACCEPT_ALL      (ACCEPT_STRING | ACCEPT_CTYPE | ACCEPT_CDATA)
 #define CONSIDER_FN_AS_FNPTR  8
 
-static CTypeDescrObject *_ffi_bad_type(FFIObject *ffi, char *input_text)
+static CTypeDescrObject *_ffi_bad_type(FFIObject *ffi, const char *input_text)
 {
     size_t length = strlen(input_text);
     char *extra;
@@ -188,7 +188,7 @@
         PyObject *x = PyDict_GetItem(types_dict, arg);
 
         if (x == NULL) {
-            char *input_text = PyText_AS_UTF8(arg);
+            const char *input_text = PyText_AS_UTF8(arg);
             int err, index = parse_c_type(&ffi->info, input_text);
             if (index < 0)
                 return _ffi_bad_type(ffi, input_text);
diff --git a/c/file_emulator.h b/c/file_emulator.h
--- a/c/file_emulator.h
+++ b/c/file_emulator.h
@@ -33,7 +33,7 @@
     PyObject *ob, *ob_capsule = NULL, *ob_mode = NULL;
     FILE *f;
     int fd;
-    char *mode;
+    const char *mode;
 
     ob = PyObject_CallMethod(ob_file, "flush", NULL);
     if (ob == NULL)
diff --git a/c/lib_obj.c b/c/lib_obj.c
--- a/c/lib_obj.c
+++ b/c/lib_obj.c
@@ -85,7 +85,8 @@
 }
 
 static void cdlopen_close_ignore_errors(void *libhandle);  /* forward */
-static void *cdlopen_fetch(PyObject *libname, void *libhandle, char *symbol);
+static void *cdlopen_fetch(PyObject *libname, void *libhandle,
+                           const char *symbol);
 
 static void lib_dealloc(LibObject *lib)
 {
@@ -127,7 +128,7 @@
     int i, type_index = _CFFI_GETARG(g->type_op);
     _cffi_opcode_t *opcodes = lib->l_types_builder->ctx.types;
     static const char *const format = ";\n\nCFFI C function from %s.lib";
-    char *libname = PyText_AS_UTF8(lib->l_libname);
+    const char *libname = PyText_AS_UTF8(lib->l_libname);
     struct funcbuilder_s funcbuilder;
 
     /* return type: */
@@ -206,7 +207,7 @@
     const struct _cffi_global_s *g;
     CTypeDescrObject *ct;
     builder_c_t *types_builder = lib->l_types_builder;
-    char *s = PyText_AsUTF8(name);
+    const char *s = PyText_AsUTF8(name);
     if (s == NULL)
         return NULL;
 
@@ -493,7 +494,7 @@
 
 static PyObject *lib_getattr(LibObject *lib, PyObject *name)
 {
-    char *p;
+    const char *p;
     PyObject *x;
     LIB_GET_OR_CACHE_ADDR(x, lib, name, goto missing);
 
@@ -530,6 +531,13 @@
         PyErr_Clear();
         return PyText_FromFormat("%s.lib", PyText_AS_UTF8(lib->l_libname));
     }
+#if PY_MAJOR_VERSION >= 3
+    if (strcmp(p, "__loader__") == 0 || strcmp(p, "__spec__") == 0) {
+        /* some more module-like behavior hacks */
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+#endif
     return NULL;
 }
 
diff --git a/c/minibuffer.h b/c/minibuffer.h
--- a/c/minibuffer.h
+++ b/c/minibuffer.h
@@ -56,14 +56,17 @@
     }
 }
 
+/* forward: from _cffi_backend.c */
+static int _fetch_as_buffer(PyObject *x, Py_buffer *view, int writable_only);
+
 static int mb_ass_slice(MiniBufferObj *self,
                         Py_ssize_t left, Py_ssize_t right, PyObject *other)
 {
-    const void *buffer;
-    Py_ssize_t buffer_len, count;
+    Py_ssize_t count;
     Py_ssize_t size = self->mb_size;
+    Py_buffer src_view;
 
-    if (PyObject_AsReadBuffer(other, &buffer, &buffer_len) < 0)
+    if (_fetch_as_buffer(other, &src_view, 0) < 0)
         return -1;
 
     if (left < 0)     left = 0;
@@ -71,12 +74,14 @@
     if (left > right) left = right;
 
     count = right - left;
-    if (count != buffer_len) {
+    if (count != src_view.len) {
+        PyBuffer_Release(&src_view);
         PyErr_SetString(PyExc_ValueError,
                         "right operand length must match slice length");
         return -1;
     }
-    memcpy(self->mb_data + left, buffer, count);
+    memcpy(self->mb_data + left, src_view.buf, count);
+    PyBuffer_Release(&src_view);
     return 0;
 }
 
@@ -232,6 +237,14 @@
 
 #if PY_MAJOR_VERSION >= 3
 /* pfffffffffffff pages of copy-paste from listobject.c */
+
+/* pfffffffffffff#2: the PySlice_GetIndicesEx() *macro* should not
+   be called, because C extension modules compiled with it differ
+   on ABI between 3.6.0, 3.6.1 and 3.6.2. */
+#if PY_VERSION_HEX < 0x03070000 && defined(PySlice_GetIndicesEx) && !defined(PYPY_VERSION)
+#undef PySlice_GetIndicesEx
+#endif
+
 static PyObject *mb_subscript(MiniBufferObj *self, PyObject *item)
 {
     if (PyIndex_Check(item)) {
diff --git a/c/test_c.py b/c/test_c.py
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -12,7 +12,7 @@
 # ____________________________________________________________
 
 import sys
-assert __version__ == "1.11.0", ("This test_c.py file is for testing a version"
+assert __version__ == "1.11.1", ("This test_c.py file is for testing a version"
                                  " of cffi that differs from the one that we"
                                  " get from 'import _cffi_backend'")
 if sys.version_info < (3,):
diff --git a/cffi/__init__.py b/cffi/__init__.py
--- a/cffi/__init__.py
+++ b/cffi/__init__.py
@@ -4,8 +4,8 @@
 from .api import FFI
 from .error import CDefError, FFIError, VerificationError, VerificationMissing
 
-__version__ = "1.11.0"
-__version_info__ = (1, 11, 0)
+__version__ = "1.11.1"
+__version_info__ = (1, 11, 1)
 
 # 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/cffi/_embedding.h b/cffi/_embedding.h
--- a/cffi/_embedding.h
+++ b/cffi/_embedding.h
@@ -247,7 +247,7 @@
 
         if (f != NULL && f != Py_None) {
             PyFile_WriteString("\nFrom: " _CFFI_MODULE_NAME
-                               "\ncompiled with cffi version: 1.11.0"
+                               "\ncompiled with cffi version: 1.11.1"
                                "\n_cffi_backend module: ", f);
             modules = PyImport_GetModuleDict();
             mod = PyDict_GetItemString(modules, "_cffi_backend");
diff --git a/doc/source/conf.py b/doc/source/conf.py
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -47,7 +47,7 @@
 # The short X.Y version.
 version = '1.11'
 # The full version, including alpha/beta/rc tags.
-release = '1.11.0'
+release = '1.11.1'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff --git a/doc/source/installation.rst b/doc/source/installation.rst
--- a/doc/source/installation.rst
+++ b/doc/source/installation.rst
@@ -51,13 +51,13 @@
 
 Download and Installation:
 
-* https://pypi.python.org/packages/4e/32/4070bdf32812c89eb635c80880a5caa2e0189aa7999994c265577e5154f3/cffi-1.11.0.tar.gz#md5=2c5939cc2fa0183fe0c2fcb6a4f1994d
+* https://pypi.python.org/pypi/cffi
 
-   - MD5: 2c5939cc2fa0183fe0c2fcb6a4f1994d
+   - MD5: ...
 
-   - SHA: 93cb5aaf152e19f9d4082a723aa2396e9cd5d93f
+   - SHA: ...
 
-   - SHA256: 5f4ff33371c6969b39b293d9771ee91e81d26f9129be093ca1b7be357fcefd15
+   - SHA256: ...
 
 * Or grab the most current version from the `Bitbucket page`_:
   ``hg clone https://bitbucket.org/cffi/cffi``
diff --git a/doc/source/whatsnew.rst b/doc/source/whatsnew.rst
--- a/doc/source/whatsnew.rst
+++ b/doc/source/whatsnew.rst
@@ -3,6 +3,17 @@
 ======================
 
 
+v1.11.1
+=======
+
+* Fix tests, remove deprecated C API usage
+
+* Fix for 3.6.0/3.6.1 being incompatible with each other unless we hack
+  (cpython issue `#29943`_)
+  
+.. _`#29943`: https://bugs.python.org/issue29943
+
+
 v1.11
 =====
 
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -186,7 +186,7 @@
 
 `Mailing list <https://groups.google.com/forum/#!forum/python-cffi>`_
 """,
-        version='1.11.0',
+        version='1.11.1',
         packages=['cffi'] if cpython else [],
         package_data={'cffi': ['_cffi_include.h', 'parse_c_type.h', 
                                '_embedding.h', '_cffi_errors.h']}
@@ -231,6 +231,7 @@
             'Programming Language :: Python :: 3.3',
             'Programming Language :: Python :: 3.4',
             'Programming Language :: Python :: 3.5',
+            'Programming Language :: Python :: 3.6',
             'Programming Language :: Python :: Implementation :: CPython',
             'Programming Language :: Python :: Implementation :: PyPy',
         ],
diff --git a/testing/cffi0/test_verify.py b/testing/cffi0/test_verify.py
--- a/testing/cffi0/test_verify.py
+++ b/testing/cffi0/test_verify.py
@@ -2455,9 +2455,18 @@
     pt = lib.call2(lib.cb2)
     assert (pt.x, pt.y) == (99*500*999, -99*500*999)
 
+def _only_test_on_linux_intel():
+    if not sys.platform.startswith('linux'):
+        py.test.skip('only running the memory-intensive test on Linux')
+    import platform
+    machine = platform.machine()
+    if 'x86' not in machine and 'x64' not in machine:
+        py.test.skip('only running the memory-intensive test on x86/x64')
+
 def test_ffi_gc_size_arg():
     # with PyPy's GC, these calls to ffi.gc() would rapidly consume
     # 40 GB of RAM without the third argument
+    _only_test_on_linux_intel()
     ffi = FFI()
     ffi.cdef("void *malloc(size_t); void free(void *);")
     lib = ffi.verify(r"""
@@ -2466,8 +2475,8 @@
     for i in range(2000):
         p = lib.malloc(20*1024*1024)    # 20 MB
         p1 = ffi.cast("char *", p)
-        for j in xrange(0, 20*1024*1024, 4096):
-            p1[j] = '!'
+        for j in range(0, 20*1024*1024, 4096):
+            p1[j] = b'!'
         p = ffi.gc(p, lib.free, 20*1024*1024)
         del p
 
@@ -2477,6 +2486,7 @@
     # is skipped on CPython, where it eats all the memory.
     if '__pypy__' not in sys.builtin_module_names:
         py.test.skip("find a way to tweak the cyclic GC of CPython")
+    _only_test_on_linux_intel()
     ffi = FFI()
     ffi.cdef("void *malloc(size_t); void free(void *);")
     lib = ffi.verify(r"""
@@ -2487,8 +2497,8 @@
     for i in range(2000):
         p = lib.malloc(50*1024*1024)    # 50 MB
         p1 = ffi.cast("char *", p)
-        for j in xrange(0, 50*1024*1024, 4096):
-            p1[j] = '!'
+        for j in range(0, 50*1024*1024, 4096):
+            p1[j] = b'!'
         p = ffi.gc(p, lib.free, 50*1024*1024)
         x = X()
         x.p = p
@@ -2506,8 +2516,8 @@
         pass
     for i in range(2000):
         p = ffi.new("char[]", 50*1024*1024)    # 50 MB
-        for j in xrange(0, 50*1024*1024, 4096):
-            p[j] = '!'
+        for j in range(0, 50*1024*1024, 4096):
+            p[j] = b'!'
         x = X()
         x.p = p
         x.cyclic = x
diff --git a/testing/cffi0/test_version.py b/testing/cffi0/test_version.py
--- a/testing/cffi0/test_version.py
+++ b/testing/cffi0/test_version.py
@@ -36,7 +36,7 @@
     v = cffi.__version__.replace('+', '')
     p = os.path.join(parent, 'doc', 'source', 'installation.rst')
     content = open(p).read()
-    assert ("cffi/cffi-%s.tar.gz" % v) in content
+    assert ("/cffi-%s.tar.gz" % v) in content
 
 def test_setup_version():
     parent = os.path.dirname(os.path.dirname(cffi.__file__))
diff --git a/testing/cffi1/test_verify1.py b/testing/cffi1/test_verify1.py
--- a/testing/cffi1/test_verify1.py
+++ b/testing/cffi1/test_verify1.py
@@ -2294,7 +2294,16 @@
     assert ffi.typeof("UINT_PTR") is ffi.typeof(expected)
     assert ffi.typeof("PTSTR") is ffi.typeof("wchar_t *")
 
-def test_gc_pypy_size_arg():
+def _only_test_on_linux_intel():
+    if not sys.platform.startswith('linux'):
+        py.test.skip('only running the memory-intensive test on Linux')
+    import platform
+    machine = platform.machine()
+    if 'x86' not in machine and 'x64' not in machine:
+        py.test.skip('only running the memory-intensive test on x86/x64')
+
+def test_ffi_gc_size_arg():
+    _only_test_on_linux_intel()
     ffi = FFI()
     ffi.cdef("void *malloc(size_t); void free(void *);")
     lib = ffi.verify(r"""
@@ -2303,8 +2312,8 @@
     for i in range(2000):
         p = lib.malloc(20*1024*1024)    # 20 MB
         p1 = ffi.cast("char *", p)
-        for j in xrange(0, 20*1024*1024, 4096):
-            p1[j] = '!'
+        for j in range(0, 20*1024*1024, 4096):
+            p1[j] = b'!'
         p = ffi.gc(p, lib.free, 20*1024*1024)
         del p
         # with PyPy's GC, the above would rapidly consume 40 GB of RAM
@@ -2316,6 +2325,7 @@
     # is skipped on CPython, where it eats all the memory.
     if '__pypy__' not in sys.builtin_module_names:
         py.test.skip("find a way to tweak the cyclic GC of CPython")
+    _only_test_on_linux_intel()
     ffi = FFI()
     ffi.cdef("void *malloc(size_t); void free(void *);")
     lib = ffi.verify(r"""
@@ -2326,8 +2336,8 @@
     for i in range(2000):
         p = lib.malloc(50*1024*1024)    # 50 MB
         p1 = ffi.cast("char *", p)
-        for j in xrange(0, 50*1024*1024, 4096):
-            p1[j] = '!'
+        for j in range(0, 50*1024*1024, 4096):
+            p1[j] = b'!'
         p = ffi.gc(p, lib.free, 50*1024*1024)
         x = X()
         x.p = p
@@ -2345,8 +2355,8 @@
         pass
     for i in range(2000):
         p = ffi.new("char[]", 50*1024*1024)    # 50 MB
-        for j in xrange(0, 50*1024*1024, 4096):
-            p[j] = '!'
+        for j in range(0, 50*1024*1024, 4096):
+            p[j] = b'!'
         x = X()
         x.p = p
         x.cyclic = x


More information about the pypy-commit mailing list