Author: Armin Rigo <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit