Author: Richard Plangger <[email protected]>
Branch:
Changeset: r2854:9af655eac351
Date: 2017-01-04 15:52 +0100
http://bitbucket.org/cffi/cffi/changeset/9af655eac351/
Log: merge strbuf-as-buffer
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -6134,54 +6134,18 @@
return 0;
}
-static int invalid_input_buffer_type(PyObject *x)
-{
- /* From PyPy 5.4, from_buffer() accepts strings (but still not buffers
- or memoryviews on strings). */
- if (PyBytes_Check(x))
- return 0;
-
-#if PY_MAJOR_VERSION < 3
- if (PyBuffer_Check(x)) {
- /* XXX fish fish fish in an inofficial way */
- typedef struct {
- PyObject_HEAD
- PyObject *b_base;
- } _my_PyBufferObject;
-
- _my_PyBufferObject *b = (_my_PyBufferObject *)x;
- x = b->b_base;
- if (x == NULL)
- return 0;
- }
- else
-#endif
-#if PY_MAJOR_VERSION > 2 || PY_MINOR_VERSION > 6
- if (PyMemoryView_Check(x)) {
- x = PyMemoryView_GET_BASE(x);
- if (x == NULL)
- return 0;
- }
- else
-#endif
- ;
-
- if (PyBytes_Check(x) || PyUnicode_Check(x))
- return 1;
- /* From PyPy 5.2, bytearray buffers can fetch a raw pointer, so
- there is no reason any more to prevent from_buffer(bytearray()). */
- return 0;
-}
-
static PyObject *direct_from_buffer(CTypeDescrObject *ct, PyObject *x)
{
CDataObject *cd;
Py_buffer *view;
- if (invalid_input_buffer_type(x)) {
+ /* PyPy 5.7 can obtain buffers for string (python 2)
+ or bytes (python 3). from_buffer(u"foo") is disallowed.
+ */
+ if (PyUnicode_Check(x)) {
PyErr_SetString(PyExc_TypeError,
- "from_buffer() cannot return the address of the "
- "raw string within a "STR_OR_BYTES" or unicode
object");
+ "from_buffer() cannot return the address "
+ "of a unicode object");
return NULL;
}
diff --git a/c/test_c.py b/c/test_c.py
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -3438,16 +3438,26 @@
except ImportError:
pass
else:
- # from_buffer(buffer(b"foo")) does not work, because it's not
- # implemented on pypy; only from_buffer(b"foo") works.
- py.test.raises(TypeError, from_buffer, BCharA, buffer(b"foo"))
- py.test.raises(TypeError, from_buffer, BCharA, buffer(u+"foo"))
+ # Python 2 only
+ contents = from_buffer(BCharA, buffer(b"foo"))
+ assert len(contents) == len(p1)
+ for i in range(len(contents)):
+ assert contents[i] == p1[i]
+ p4 = buffer(u+"foo")
+ contents = from_buffer(BCharA, buffer(u+"foo"))
+ assert len(contents) == len(p4)
+ for i in range(len(contents)):
+ assert contents[i] == p4[i]
try:
from __builtin__ import memoryview
except ImportError:
pass
else:
- py.test.raises(TypeError, from_buffer, BCharA, memoryview(b"foo"))
+ contents = from_buffer(BCharA, memoryview(b"foo"))
+ assert len(contents) == len(p1)
+ for i in range(len(contents)):
+ assert contents[i] == p1[i]
+
def test_from_buffer_bytearray():
a = bytearray(b"xyz")
diff --git a/doc/source/ref.rst b/doc/source/ref.rst
--- a/doc/source/ref.rst
+++ b/doc/source/ref.rst
@@ -175,9 +175,8 @@
**ffi.from_buffer(python_buffer)**: return a ``<cdata 'char[]'>`` that
points to the data of the given Python object, which must support the
buffer interface. This is the opposite of ``ffi.buffer()``. It gives
-a reference to the existing data, not a copy; for this
-reason, and for PyPy compatibility, it does not work with the built-in
-type unicode; nor buffers/memoryviews to byte or unicode strings.
+a reference to the existing data, not a copy; It does not work with the
built-in
+type unicode.
It is meant to be used on objects
containing large quantities of raw data, like bytearrays
or ``array.array`` or numpy
diff --git a/doc/source/whatsnew.rst b/doc/source/whatsnew.rst
--- a/doc/source/whatsnew.rst
+++ b/doc/source/whatsnew.rst
@@ -23,6 +23,8 @@
* Add support for some obscure compilers (non-msvc, non-gcc, non-icc,
non-clang)
+* ``ffi.from_buffer`` allows Python 2 strings and Python 3 bytes to be
+ passed. Unicode is the only type disallowed.
v1.9
====
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit