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