Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP4:Update
python-cffi.27871
require-writable.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File require-writable.patch of Package python-cffi.27871
Index: cffi-1.11.5/c/_cffi_backend.c =================================================================== --- cffi-1.11.5.orig/c/_cffi_backend.c +++ cffi-1.11.5/c/_cffi_backend.c @@ -6679,7 +6679,8 @@ static int _my_PyObject_GetContiguousBuf return 0; } -static PyObject *direct_from_buffer(CTypeDescrObject *ct, PyObject *x) +static PyObject *direct_from_buffer(CTypeDescrObject *ct, PyObject *x, + int require_writable) { CDataObject *cd; Py_buffer *view; @@ -6699,7 +6700,7 @@ static PyObject *direct_from_buffer(CTyp PyErr_NoMemory(); return NULL; } - if (_my_PyObject_GetContiguousBuffer(x, view, 0) < 0) + if (_my_PyObject_GetContiguousBuffer(x, view, require_writable) < 0) goto error1; cd = (CDataObject *)PyObject_GC_New(CDataObject_owngc_frombuf, @@ -6727,15 +6728,17 @@ static PyObject *b_from_buffer(PyObject { CTypeDescrObject *ct; PyObject *x; + int require_writable = 0; - if (!PyArg_ParseTuple(args, "O!O", &CTypeDescr_Type, &ct, &x)) + if (!PyArg_ParseTuple(args, "O!O|i", &CTypeDescr_Type, &ct, &x, + &require_writable)) return NULL; if (!(ct->ct_flags & CT_IS_UNSIZED_CHAR_A)) { PyErr_Format(PyExc_TypeError, "needs 'char[]', got '%s'", ct->ct_name); return NULL; } - return direct_from_buffer(ct, x); + return direct_from_buffer(ct, x, require_writable); } static int _fetch_as_buffer(PyObject *x, Py_buffer *view, int writable_only) Index: cffi-1.11.5/c/ffi_obj.c =================================================================== --- cffi-1.11.5.orig/c/ffi_obj.c +++ cffi-1.11.5/c/ffi_obj.c @@ -697,9 +697,16 @@ PyDoc_STRVAR(ffi_from_buffer_doc, "containing large quantities of raw data in some other format, like\n" "'array.array' or numpy arrays."); -static PyObject *ffi_from_buffer(PyObject *self, PyObject *arg) +static PyObject *ffi_from_buffer(PyObject *self, PyObject *args, PyObject *kwds) { - return direct_from_buffer(g_ct_chararray, arg); + PyObject *arg; + int require_writable = 0; + static char *keywords[] = {"python_buffer", "require_writable", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i:from_buffer", keywords, + &arg, &require_writable)) + return NULL; + return direct_from_buffer(g_ct_chararray, arg, require_writable); } PyDoc_STRVAR(ffi_gc_doc, @@ -1082,7 +1089,7 @@ static PyMethodDef ffi_methods[] = { {"cast", (PyCFunction)ffi_cast, METH_VARARGS, ffi_cast_doc}, {"dlclose", (PyCFunction)ffi_dlclose, METH_VARARGS, ffi_dlclose_doc}, {"dlopen", (PyCFunction)ffi_dlopen, METH_VARARGS, ffi_dlopen_doc}, - {"from_buffer",(PyCFunction)ffi_from_buffer,METH_O, ffi_from_buffer_doc}, + {"from_buffer",(PyCFunction)ffi_from_buffer,METH_VKW, ffi_from_buffer_doc}, {"from_handle",(PyCFunction)ffi_from_handle,METH_O, ffi_from_handle_doc}, {"gc", (PyCFunction)ffi_gc, METH_VKW, ffi_gc_doc}, {"getctype", (PyCFunction)ffi_getctype, METH_VKW, ffi_getctype_doc}, Index: cffi-1.11.5/c/test_c.py =================================================================== --- cffi-1.11.5.orig/c/test_c.py +++ cffi-1.11.5/c/test_c.py @@ -3694,6 +3694,18 @@ def test_from_buffer_more_cases(): check(4 | 8, "CHB", "GTB") check(4 | 16, "CHB", "ROB") +def test_from_buffer_require_writable(): + BChar = new_primitive_type("char") + BCharP = new_pointer_type(BChar) + BCharA = new_array_type(BCharP, None) + p1 = from_buffer(BCharA, b"foo", False) + assert p1 == from_buffer(BCharA, b"foo", False) + py.test.raises((TypeError, BufferError), from_buffer, BCharA, b"foo", True) + ba = bytearray(b"foo") + p1 = from_buffer(BCharA, ba, True) + p1[0] = b"g" + assert ba == b"goo" + def test_memmove(): Short = new_primitive_type("short") ShortA = new_array_type(new_pointer_type(Short), None) Index: cffi-1.11.5/cffi/api.py =================================================================== --- cffi-1.11.5.orig/cffi/api.py +++ cffi-1.11.5/cffi/api.py @@ -338,7 +338,7 @@ class FFI(object): # """ # note that 'buffer' is a type, set on this instance by __init__ - def from_buffer(self, python_buffer): + def from_buffer(self, python_buffer, require_writable=False): """Return a <cdata 'char[]'> that points to the data of the given Python object, which must support the buffer interface. Note that this is not meant to be used on the built-in types @@ -346,7 +346,8 @@ class FFI(object): but only on objects containing large quantities of raw data in some other format, like 'array.array' or numpy arrays. """ - return self._backend.from_buffer(self.BCharA, python_buffer) + return self._backend.from_buffer(self.BCharA, python_buffer, + require_writable) def memmove(self, dest, src, n): """ffi.memmove(dest, src, n) copies n bytes of memory from src to dest. Index: cffi-1.11.5/doc/source/ref.rst =================================================================== --- cffi-1.11.5.orig/doc/source/ref.rst +++ cffi-1.11.5/doc/source/ref.rst @@ -188,7 +188,8 @@ byte strings). Use ``buf[:]`` instead. *New in version 1.10:* ``ffi.buffer`` is now the type of the returned buffer objects; ``ffi.buffer()`` actually calls the constructor. -**ffi.from_buffer(python_buffer)**: return a ``<cdata 'char[]'>`` that +**ffi.from_buffer(python_buffer, require_writable=False)**: +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. @@ -216,6 +217,18 @@ bytearray objects were supported in vers resize the bytearray, the ``<cdata>`` object will point to freed memory); and byte strings were supported in version 1.8 onwards. +*New in version 1.12:* added the ``require_writable`` argument. If set to +True, the function fails if the buffer obtained from ``python_buffer`` is +read-only (e.g. if ``python_buffer`` is a byte string). The exact exception is +raised by the object itself, and for things like bytes it varies with the +Python version, so don't rely on it. (Before version 1.12, the same effect can +be achieved with a hack: call ``ffi.memmove(python_buffer, b"", 0)``. This has +no effect if the object is writable, but fails if it is read-only.) + +Please keep in mind that CFFI does not implement the C keyword ``const``: even +if you set ``require_writable`` to False explicitly, you still get a regular +read-write cdata pointer. + ffi.memmove() +++++++++++++ Index: cffi-1.11.5/doc/source/whatsnew.rst =================================================================== --- cffi-1.11.5.orig/doc/source/whatsnew.rst +++ cffi-1.11.5/doc/source/whatsnew.rst @@ -37,6 +37,10 @@ v1.11.5 .. _`Issue #358`: https://bitbucket.org/cffi/cffi/issues/358/ .. _`Issue #357`: https://bitbucket.org/cffi/cffi/issues/357/ +* ``ffi.from_buffer()`` takes a new keyword argument ``require_writable``. + When set to True, it asks the object passed in to raise an exception if + it is read-only. + v1.11.4 ======= Index: cffi-1.11.5/testing/cffi0/test_ffi_backend.py =================================================================== --- cffi-1.11.5.orig/testing/cffi0/test_ffi_backend.py +++ cffi-1.11.5/testing/cffi0/test_ffi_backend.py @@ -326,6 +326,16 @@ class TestBitfield: assert ffi.typeof(c) is ffi.typeof("char[]") ffi.cast("unsigned short *", c)[1] += 500 assert list(a) == [10000, 20500, 30000] + assert c == ffi.from_buffer(a, True) + assert c == ffi.from_buffer(a, require_writable=True) + # + p = ffi.from_buffer(b"abcd") + assert p[2] == b"c" + # + assert p == ffi.from_buffer(b"abcd", False) + py.test.raises((TypeError, BufferError), ffi.from_buffer, b"abcd", True) + py.test.raises((TypeError, BufferError), ffi.from_buffer, b"abcd", + require_writable=True) def test_memmove(self): ffi = FFI() Index: cffi-1.11.5/testing/cffi1/test_ffi_obj.py =================================================================== --- cffi-1.11.5.orig/testing/cffi1/test_ffi_obj.py +++ cffi-1.11.5/testing/cffi1/test_ffi_obj.py @@ -243,6 +243,16 @@ def test_ffi_from_buffer(): assert ffi.typeof(c) is ffi.typeof("char[]") ffi.cast("unsigned short *", c)[1] += 500 assert list(a) == [10000, 20500, 30000] + assert c == ffi.from_buffer(a, True) + assert c == ffi.from_buffer(a, require_writable=True) + # + p = ffi.from_buffer(b"abcd") + assert p[2] == b"c" + # + assert p == ffi.from_buffer(b"abcd", False) + py.test.raises((TypeError, BufferError), ffi.from_buffer, b"abcd", True) + py.test.raises((TypeError, BufferError), ffi.from_buffer, b"abcd", + require_writable=True) def test_memmove(): ffi = _cffi1_backend.FFI() Index: cffi-1.11.5/testing/cffi1/test_new_ffi_1.py =================================================================== --- cffi-1.11.5.orig/testing/cffi1/test_new_ffi_1.py +++ cffi-1.11.5/testing/cffi1/test_new_ffi_1.py @@ -1653,6 +1653,16 @@ class TestNewFFI1: assert ffi.typeof(c) is ffi.typeof("char[]") ffi.cast("unsigned short *", c)[1] += 500 assert list(a) == [10000, 20500, 30000] + assert c == ffi.from_buffer(a, True) + assert c == ffi.from_buffer(a, require_writable=True) + # + p = ffi.from_buffer(b"abcd") + assert p[2] == b"c" + # + assert p == ffi.from_buffer(b"abcd", False) + py.test.raises((TypeError, BufferError), ffi.from_buffer, b"abcd", True) + py.test.raises((TypeError, BufferError), ffi.from_buffer, b"abcd", + require_writable=True) def test_all_primitives(self): assert set(PRIMITIVE_TO_INDEX) == set([
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor