mirror of https://github.com/python/cpython
bpo-35845: Add order={'C', 'F', 'A'} parameter to memoryview.tobytes(). (#11730)
This commit is contained in:
parent
4860f01ac0
commit
d08ea70464
|
@ -3600,7 +3600,7 @@ copying.
|
||||||
Previous versions compared the raw memory disregarding the item format
|
Previous versions compared the raw memory disregarding the item format
|
||||||
and the logical array structure.
|
and the logical array structure.
|
||||||
|
|
||||||
.. method:: tobytes()
|
.. method:: tobytes(order=None)
|
||||||
|
|
||||||
Return the data in the buffer as a bytestring. This is equivalent to
|
Return the data in the buffer as a bytestring. This is equivalent to
|
||||||
calling the :class:`bytes` constructor on the memoryview. ::
|
calling the :class:`bytes` constructor on the memoryview. ::
|
||||||
|
@ -3616,6 +3616,13 @@ copying.
|
||||||
supports all format strings, including those that are not in
|
supports all format strings, including those that are not in
|
||||||
:mod:`struct` module syntax.
|
:mod:`struct` module syntax.
|
||||||
|
|
||||||
|
.. versionadded:: 3.8
|
||||||
|
*Order* can be {'C', 'F', 'A'}. When *order* is 'C' or 'F', the data
|
||||||
|
of the original array is converted to C or Fortran order. For contiguous
|
||||||
|
views, 'A' returns an exact copy of the physical memory. In particular,
|
||||||
|
in-memory Fortran order is preserved. For non-contiguous views, the
|
||||||
|
data is converted to C first. *order=None* is the same as *order='C'*.
|
||||||
|
|
||||||
.. method:: hex()
|
.. method:: hex()
|
||||||
|
|
||||||
Return a string object containing two hexadecimal digits for each
|
Return a string object containing two hexadecimal digits for each
|
||||||
|
|
|
@ -893,6 +893,15 @@ class TestBufferProtocol(unittest.TestCase):
|
||||||
y = ndarray(initlst, shape=shape, flags=ro, format=fmt)
|
y = ndarray(initlst, shape=shape, flags=ro, format=fmt)
|
||||||
self.assertEqual(memoryview(y), memoryview(result))
|
self.assertEqual(memoryview(y), memoryview(result))
|
||||||
|
|
||||||
|
contig_bytes = memoryview(result).tobytes()
|
||||||
|
self.assertEqual(contig_bytes, contig)
|
||||||
|
|
||||||
|
contig_bytes = memoryview(result).tobytes(order=None)
|
||||||
|
self.assertEqual(contig_bytes, contig)
|
||||||
|
|
||||||
|
contig_bytes = memoryview(result).tobytes(order='C')
|
||||||
|
self.assertEqual(contig_bytes, contig)
|
||||||
|
|
||||||
# To 'F'
|
# To 'F'
|
||||||
contig = py_buffer_to_contiguous(result, 'F', PyBUF_FULL_RO)
|
contig = py_buffer_to_contiguous(result, 'F', PyBUF_FULL_RO)
|
||||||
self.assertEqual(len(contig), nmemb * itemsize)
|
self.assertEqual(len(contig), nmemb * itemsize)
|
||||||
|
@ -905,6 +914,9 @@ class TestBufferProtocol(unittest.TestCase):
|
||||||
format=fmt)
|
format=fmt)
|
||||||
self.assertEqual(memoryview(y), memoryview(result))
|
self.assertEqual(memoryview(y), memoryview(result))
|
||||||
|
|
||||||
|
contig_bytes = memoryview(result).tobytes(order='F')
|
||||||
|
self.assertEqual(contig_bytes, contig)
|
||||||
|
|
||||||
# To 'A'
|
# To 'A'
|
||||||
contig = py_buffer_to_contiguous(result, 'A', PyBUF_FULL_RO)
|
contig = py_buffer_to_contiguous(result, 'A', PyBUF_FULL_RO)
|
||||||
self.assertEqual(len(contig), nmemb * itemsize)
|
self.assertEqual(len(contig), nmemb * itemsize)
|
||||||
|
@ -917,6 +929,9 @@ class TestBufferProtocol(unittest.TestCase):
|
||||||
y = ndarray(initlst, shape=shape, flags=f|ro, format=fmt)
|
y = ndarray(initlst, shape=shape, flags=f|ro, format=fmt)
|
||||||
self.assertEqual(memoryview(y), memoryview(result))
|
self.assertEqual(memoryview(y), memoryview(result))
|
||||||
|
|
||||||
|
contig_bytes = memoryview(result).tobytes(order='A')
|
||||||
|
self.assertEqual(contig_bytes, contig)
|
||||||
|
|
||||||
if is_memoryview_format(fmt):
|
if is_memoryview_format(fmt):
|
||||||
try:
|
try:
|
||||||
m = memoryview(result)
|
m = memoryview(result)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Add 'order' parameter to memoryview.tobytes().
|
|
@ -2120,22 +2120,39 @@ memory_tolist(PyMemoryViewObject *mv, PyObject *noargs)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
memory_tobytes(PyMemoryViewObject *self, PyObject *dummy)
|
memory_tobytes(PyMemoryViewObject *self, PyObject *args, PyObject *kwds)
|
||||||
{
|
{
|
||||||
|
static char *kwlist[] = {"order", NULL};
|
||||||
Py_buffer *src = VIEW_ADDR(self);
|
Py_buffer *src = VIEW_ADDR(self);
|
||||||
PyObject *bytes = NULL;
|
char *order = NULL;
|
||||||
|
char ord = 'C';
|
||||||
|
PyObject *bytes;
|
||||||
|
|
||||||
CHECK_RELEASED(self);
|
CHECK_RELEASED(self);
|
||||||
|
|
||||||
if (MV_C_CONTIGUOUS(self->flags)) {
|
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|z", kwlist, &order)) {
|
||||||
return PyBytes_FromStringAndSize(src->buf, src->len);
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (order) {
|
||||||
|
if (strcmp(order, "F") == 0) {
|
||||||
|
ord = 'F';
|
||||||
|
}
|
||||||
|
else if (strcmp(order, "A") == 0) {
|
||||||
|
ord = 'A';
|
||||||
|
}
|
||||||
|
else if (strcmp(order, "C") != 0) {
|
||||||
|
PyErr_SetString(PyExc_ValueError,
|
||||||
|
"order must be 'C', 'F' or 'A'");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes = PyBytes_FromStringAndSize(NULL, src->len);
|
bytes = PyBytes_FromStringAndSize(NULL, src->len);
|
||||||
if (bytes == NULL)
|
if (bytes == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (buffer_to_contiguous(PyBytes_AS_STRING(bytes), src, 'C') < 0) {
|
if (PyBuffer_ToContiguous(PyBytes_AS_STRING(bytes), src, src->len, ord) < 0) {
|
||||||
Py_DECREF(bytes);
|
Py_DECREF(bytes);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -2156,10 +2173,15 @@ memory_hex(PyMemoryViewObject *self, PyObject *dummy)
|
||||||
return _Py_strhex(src->buf, src->len);
|
return _Py_strhex(src->buf, src->len);
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes = memory_tobytes(self, dummy);
|
bytes = PyBytes_FromStringAndSize(NULL, src->len);
|
||||||
if (bytes == NULL)
|
if (bytes == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if (PyBuffer_ToContiguous(PyBytes_AS_STRING(bytes), src, src->len, 'C') < 0) {
|
||||||
|
Py_DECREF(bytes);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
ret = _Py_strhex(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
|
ret = _Py_strhex(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
|
||||||
Py_DECREF(bytes);
|
Py_DECREF(bytes);
|
||||||
|
|
||||||
|
@ -3061,9 +3083,13 @@ PyDoc_STRVAR(memory_release_doc,
|
||||||
\n\
|
\n\
|
||||||
Release the underlying buffer exposed by the memoryview object.");
|
Release the underlying buffer exposed by the memoryview object.");
|
||||||
PyDoc_STRVAR(memory_tobytes_doc,
|
PyDoc_STRVAR(memory_tobytes_doc,
|
||||||
"tobytes($self, /)\n--\n\
|
"tobytes($self, /, order=None)\n--\n\
|
||||||
\n\
|
\n\
|
||||||
Return the data in the buffer as a byte string.");
|
Return the data in the buffer as a byte string. Order can be {'C', 'F', 'A'}.\n\
|
||||||
|
When order is 'C' or 'F', the data of the original array is converted to C or\n\
|
||||||
|
Fortran order. For contiguous views, 'A' returns an exact copy of the physical\n\
|
||||||
|
memory. In particular, in-memory Fortran order is preserved. For non-contiguous\n\
|
||||||
|
views, the data is converted to C first. order=None is the same as order='C'.");
|
||||||
PyDoc_STRVAR(memory_hex_doc,
|
PyDoc_STRVAR(memory_hex_doc,
|
||||||
"hex($self, /)\n--\n\
|
"hex($self, /)\n--\n\
|
||||||
\n\
|
\n\
|
||||||
|
@ -3083,7 +3109,7 @@ Return a readonly version of the memoryview.");
|
||||||
|
|
||||||
static PyMethodDef memory_methods[] = {
|
static PyMethodDef memory_methods[] = {
|
||||||
{"release", (PyCFunction)memory_release, METH_NOARGS, memory_release_doc},
|
{"release", (PyCFunction)memory_release, METH_NOARGS, memory_release_doc},
|
||||||
{"tobytes", (PyCFunction)memory_tobytes, METH_NOARGS, memory_tobytes_doc},
|
{"tobytes", (PyCFunction)memory_tobytes, METH_VARARGS|METH_KEYWORDS, memory_tobytes_doc},
|
||||||
{"hex", (PyCFunction)memory_hex, METH_NOARGS, memory_hex_doc},
|
{"hex", (PyCFunction)memory_hex, METH_NOARGS, memory_hex_doc},
|
||||||
{"tolist", (PyCFunction)memory_tolist, METH_NOARGS, memory_tolist_doc},
|
{"tolist", (PyCFunction)memory_tolist, METH_NOARGS, memory_tolist_doc},
|
||||||
{"cast", (PyCFunction)(void(*)(void))memory_cast, METH_VARARGS|METH_KEYWORDS, memory_cast_doc},
|
{"cast", (PyCFunction)(void(*)(void))memory_cast, METH_VARARGS|METH_KEYWORDS, memory_cast_doc},
|
||||||
|
|
Loading…
Reference in New Issue