Author: Armin Rigo <ar...@tunes.org>
Branch: release-1.8
Changeset: r2772:86bff8a11651
Date: 2016-09-17 11:31 +0200
http://bitbucket.org/cffi/cffi/changeset/86bff8a11651/

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.8.2"
+#define CFFI_VERSION  "1.8.3"
 
 #ifdef MS_WIN32
 #include <windows.h>
@@ -128,7 +128,7 @@
 #define CT_VOID             512    /* void */
 
 /* other flags that may also be set in addition to the base flag: */
-#define CT_CAST_ANYTHING         1024    /* 'char *' and 'void *' only */
+#define CT_IS_VOIDCHAR_PTR       1024
 #define CT_PRIMITIVE_FITS_LONG   2048
 #define CT_IS_OPAQUE             4096
 #define CT_IS_ENUM               8192
@@ -1358,9 +1358,26 @@
             }
         }
         if (ctinit != ct) {
-            if ((ct->ct_flags & CT_CAST_ANYTHING) ||
-                (ctinit->ct_flags & CT_CAST_ANYTHING))
-                ;   /* accept void* or char* as either source or target */
+            int combined_flags = ct->ct_flags | ctinit->ct_flags;
+            if (combined_flags & CT_IS_VOID_PTR)
+                ;   /* accept "void *" as either source or target */
+            else if (combined_flags & CT_IS_VOIDCHAR_PTR) {
+                /* for backward compatibility, accept "char *" as either
+                   source of target.  This is not what C does, though,
+                   so emit a warning that will eventually turn into an
+                   error. */
+                char *msg = (ct->ct_flags & CT_IS_VOIDCHAR_PTR ?
+                    "implicit cast to 'char *' from a different pointer type: "
+                    "will be forbidden in the future (check that the types "
+                    "are as you expect; use an explicit ffi.cast() if they "
+                    "are correct)" :
+                    "implicit cast from 'char *' to a different pointer type: "
+                    "will be forbidden in the future (check that the types "
+                    "are as you expect; use an explicit ffi.cast() if they "
+                    "are correct)");
+                if (PyErr_WarnEx(PyExc_UserWarning, msg, 1))
+                    return -1;
+            }
             else {
                 expected = "pointer to same type";
                 goto cannot_convert;
@@ -2476,7 +2493,7 @@
     if (PyBytes_Check(init)) {
         /* from a string: just returning the string here is fine.
            We assume that the C code won't modify the 'char *' data. */
-        if ((ctptr->ct_flags & CT_CAST_ANYTHING) ||
+        if ((ctptr->ct_flags & CT_IS_VOIDCHAR_PTR) ||
             ((ctitem->ct_flags & (CT_PRIMITIVE_SIGNED|CT_PRIMITIVE_UNSIGNED))
              && (ctitem->ct_size == sizeof(char)))) {
 #if defined(CFFI_MEM_DEBUG) || defined(CFFI_MEM_LEAK)
@@ -3929,7 +3946,7 @@
     if ((ctitem->ct_flags & CT_VOID) ||
         ((ctitem->ct_flags & CT_PRIMITIVE_CHAR) &&
          ctitem->ct_size == sizeof(char)))
-        td->ct_flags |= CT_CAST_ANYTHING;   /* 'void *' or 'char *' only */
+        td->ct_flags |= CT_IS_VOIDCHAR_PTR;   /* 'void *' or 'char *' only */
     unique_key[0] = ctitem;
     return get_unique_type(td, unique_key, 1);
 }
@@ -5903,7 +5920,7 @@
         return NULL;
     }
     ct = ((CDataObject *)arg)->c_type;
-    if (!(ct->ct_flags & CT_CAST_ANYTHING)) {
+    if (!(ct->ct_flags & CT_IS_VOIDCHAR_PTR)) {
         PyErr_Format(PyExc_TypeError,
                      "expected a 'cdata' object with a 'void *' out of "
                      "new_handle(), got '%s'", ct->ct_name);
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.8.2", ("This test_c.py file is for testing a version"
+assert __version__ == "1.8.3", ("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,):
@@ -3676,3 +3676,27 @@
     check_dir(pp, [])
     check_dir(pp[0], ['a1', 'a2'])
     check_dir(pp[0][0], ['a1', 'a2'])
+
+def test_char_pointer_conversion():
+    import warnings
+    assert __version__.startswith(("1.8", "1.9")), (
+        "consider turning the warning into an error")
+    BCharP = new_pointer_type(new_primitive_type("char"))
+    BIntP = new_pointer_type(new_primitive_type("int"))
+    BVoidP = new_pointer_type(new_void_type())
+    z1 = cast(BCharP, 0)
+    z2 = cast(BIntP, 0)
+    z3 = cast(BVoidP, 0)
+    with warnings.catch_warnings(record=True) as w:
+        newp(new_pointer_type(BIntP), z1)    # warn
+        assert len(w) == 1
+        newp(new_pointer_type(BVoidP), z1)   # fine
+        assert len(w) == 1
+        newp(new_pointer_type(BCharP), z2)   # warn
+        assert len(w) == 2
+        newp(new_pointer_type(BVoidP), z2)   # fine
+        assert len(w) == 2
+        newp(new_pointer_type(BCharP), z3)   # fine
+        assert len(w) == 2
+        newp(new_pointer_type(BIntP), z3)    # fine
+        assert len(w) == 2
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, CDefError, FFIError
 from .ffiplatform import VerificationError, VerificationMissing
 
-__version__ = "1.8.2"
-__version_info__ = (1, 8, 2)
+__version__ = "1.8.3"
+__version_info__ = (1, 8, 3)
 
 # 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
@@ -233,7 +233,7 @@
         f = PySys_GetObject((char *)"stderr");
         if (f != NULL && f != Py_None) {
             PyFile_WriteString("\nFrom: " _CFFI_MODULE_NAME
-                               "\ncompiled with cffi version: 1.8.2"
+                               "\ncompiled with cffi version: 1.8.3"
                                "\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.8'
 # The full version, including alpha/beta/rc tags.
-release = '1.8.2'
+release = '1.8.3'
 
 # 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:
 
-* http://pypi.python.org/packages/source/c/cffi/cffi-1.8.2.tar.gz
+* http://pypi.python.org/packages/source/c/cffi/cffi-1.8.3.tar.gz
 
-   - MD5: 538f307b6c5169bba41fbfda2b070762
+   - MD5: ...
 
-   - SHA: 9d2722ba9241b232b980bb9243e12451513a8000
+   - SHA: ...
 
-   - SHA256: 2b636db1a179439d73ae0a090479e179a43df5d4eddc7e4c4067f960d4038530
+   - SHA256: ...
 
 * Or grab the most current version from the `Bitbucket page`_:
   ``hg clone https://bitbucket.org/cffi/cffi``
diff --git a/doc/source/ref.rst b/doc/source/ref.rst
--- a/doc/source/ref.rst
+++ b/doc/source/ref.rst
@@ -575,12 +575,12 @@
 +---------------+------------------------+------------------+----------------+
 |  pointers     | another <cdata> with   | a <cdata>        |``[]`` `(****)`,|
 |               | a compatible type (i.e.|                  |``+``, ``-``,   |
-|               | same type or ``char*`` |                  |bool()          |
+|               | same type              |                  |bool()          |
 |               | or ``void*``, or as an |                  |                |
 |               | array instead) `(*)`   |                  |                |
 +---------------+------------------------+                  |                |
-|  ``void *``,  | another <cdata> with   |                  |                |
-|  ``char *``   | any pointer or array   |                  |                |
+|  ``void *``   | another <cdata> with   |                  |                |
+|               | any pointer or array   |                  |                |
 |               | type                   |                  |                |
 +---------------+------------------------+                  +----------------+
 |  pointers to  | same as pointers       |                  | ``[]``, ``+``, |
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,19 @@
 ======================
 
 
+v1.8.3
+======
+
+* When passing a ``void *`` argument to a function with a different
+  pointer type, or vice-versa, the cast occurs automatically, like in C.
+  The same occurs for initialization with ``ffi.new()`` and a few other
+  places.  However, I thought that ``char *`` had the same
+  property---but I was mistaken.  In C you get the usual warning if you
+  try to give a ``char *`` to a ``char **`` argument, for example.
+  Sorry about the confusion.  This has been fixed in CFFI by giving for
+  now a warning, too.  It will turn into an error in a future version.
+
+
 v1.8.2
 ======
 
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -144,7 +144,7 @@
 
 `Mailing list <https://groups.google.com/forum/#!forum/python-cffi>`_
 """,
-        version='1.8.2',
+        version='1.8.3',
         packages=['cffi'] if cpython else [],
         package_data={'cffi': ['_cffi_include.h', 'parse_c_type.h', 
                                '_embedding.h']}
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to