mirror of https://github.com/python/cpython
bpo-15913: Implement PyBuffer_SizeFromFormat() (GH-13873)
Implement PyBuffer_SizeFromFormat() function (previously documented but not implemented): call struct.calcsize().
This commit is contained in:
parent
18f8dcfa10
commit
9e66aba999
|
@ -462,10 +462,12 @@ Buffer-related functions
|
||||||
:c:func:`PyObject_GetBuffer`.
|
:c:func:`PyObject_GetBuffer`.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: Py_ssize_t PyBuffer_SizeFromFormat(const char *)
|
.. c:function:: Py_ssize_t PyBuffer_SizeFromFormat(const char *format)
|
||||||
|
|
||||||
Return the implied :c:data:`~Py_buffer.itemsize` from :c:data:`~Py_buffer.format`.
|
Return the implied :c:data:`~Py_buffer.itemsize` from :c:data:`~Py_buffer.format`.
|
||||||
This function is not yet implemented.
|
On error, raise an exception and return -1.
|
||||||
|
|
||||||
|
.. versionadded:: 3.9
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: int PyBuffer_IsContiguous(Py_buffer *view, char order)
|
.. c:function:: int PyBuffer_IsContiguous(Py_buffer *view, char order)
|
||||||
|
|
|
@ -243,7 +243,7 @@ PyAPI_FUNC(void *) PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices);
|
||||||
|
|
||||||
/* Return the implied itemsize of the data-format area from a
|
/* Return the implied itemsize of the data-format area from a
|
||||||
struct-style description. */
|
struct-style description. */
|
||||||
PyAPI_FUNC(int) PyBuffer_SizeFromFormat(const char *);
|
PyAPI_FUNC(Py_ssize_t) PyBuffer_SizeFromFormat(const char *format);
|
||||||
|
|
||||||
/* Implementation in memoryobject.c */
|
/* Implementation in memoryobject.c */
|
||||||
PyAPI_FUNC(int) PyBuffer_ToContiguous(void *buf, Py_buffer *view,
|
PyAPI_FUNC(int) PyBuffer_ToContiguous(void *buf, Py_buffer *view,
|
||||||
|
|
|
@ -43,6 +43,11 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
numpy_array = None
|
numpy_array = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
import _testcapi
|
||||||
|
except ImportError:
|
||||||
|
_testcapi = None
|
||||||
|
|
||||||
|
|
||||||
SHORT_TEST = True
|
SHORT_TEST = True
|
||||||
|
|
||||||
|
@ -4412,6 +4417,13 @@ class TestBufferProtocol(unittest.TestCase):
|
||||||
x = ndarray([1,2,3], shape=[3], flags=ND_GETBUF_FAIL)
|
x = ndarray([1,2,3], shape=[3], flags=ND_GETBUF_FAIL)
|
||||||
self.assertRaises(BufferError, memoryview, x)
|
self.assertRaises(BufferError, memoryview, x)
|
||||||
|
|
||||||
|
@support.cpython_only
|
||||||
|
def test_pybuffer_size_from_format(self):
|
||||||
|
# basic tests
|
||||||
|
for format in ('', 'ii', '3s'):
|
||||||
|
self.assertEqual(_testcapi.PyBuffer_SizeFromFormat(format),
|
||||||
|
struct.calcsize(format))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
Implement :c:func:`PyBuffer_SizeFromFormat()` function (previously
|
||||||
|
documented but not implemented): call :func:`struct.calcsize`.
|
||||||
|
Patch by Joannah Nanjekye.
|
|
@ -3363,6 +3363,26 @@ getbuffer_with_null_view(PyObject* self, PyObject *obj)
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* PyBuffer_SizeFromFormat() */
|
||||||
|
static PyObject *
|
||||||
|
test_PyBuffer_SizeFromFormat(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
const char *format;
|
||||||
|
Py_ssize_t result;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "s:test_PyBuffer_SizeFromFormat",
|
||||||
|
&format)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = PyBuffer_SizeFromFormat(format);
|
||||||
|
if (result == -1) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PyLong_FromSsize_t(result);
|
||||||
|
}
|
||||||
|
|
||||||
/* Test that the fatal error from not having a current thread doesn't
|
/* Test that the fatal error from not having a current thread doesn't
|
||||||
cause an infinite loop. Run via Lib/test/test_capi.py */
|
cause an infinite loop. Run via Lib/test/test_capi.py */
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -5153,6 +5173,7 @@ static PyMethodDef TestMethods[] = {
|
||||||
{"test_pep3118_obsolete_write_locks", (PyCFunction)test_pep3118_obsolete_write_locks, METH_NOARGS},
|
{"test_pep3118_obsolete_write_locks", (PyCFunction)test_pep3118_obsolete_write_locks, METH_NOARGS},
|
||||||
#endif
|
#endif
|
||||||
{"getbuffer_with_null_view", getbuffer_with_null_view, METH_O},
|
{"getbuffer_with_null_view", getbuffer_with_null_view, METH_O},
|
||||||
|
{"PyBuffer_SizeFromFormat", test_PyBuffer_SizeFromFormat, METH_VARARGS},
|
||||||
{"test_buildvalue_N", test_buildvalue_N, METH_NOARGS},
|
{"test_buildvalue_N", test_buildvalue_N, METH_NOARGS},
|
||||||
{"get_args", get_args, METH_VARARGS},
|
{"get_args", get_args, METH_VARARGS},
|
||||||
{"get_kwargs", (PyCFunction)(void(*)(void))get_kwargs, METH_VARARGS|METH_KEYWORDS},
|
{"get_kwargs", (PyCFunction)(void(*)(void))get_kwargs, METH_VARARGS|METH_KEYWORDS},
|
||||||
|
|
|
@ -495,6 +495,48 @@ _Py_add_one_to_index_C(int nd, Py_ssize_t *index, const Py_ssize_t *shape)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Py_ssize_t
|
||||||
|
PyBuffer_SizeFromFormat(const char *format)
|
||||||
|
{
|
||||||
|
PyObject *structmodule = NULL;
|
||||||
|
PyObject *calcsize = NULL;
|
||||||
|
PyObject *res = NULL;
|
||||||
|
PyObject *fmt = NULL;
|
||||||
|
Py_ssize_t itemsize = -1;
|
||||||
|
|
||||||
|
structmodule = PyImport_ImportModule("struct");
|
||||||
|
if (structmodule == NULL) {
|
||||||
|
return itemsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
calcsize = PyObject_GetAttrString(structmodule, "calcsize");
|
||||||
|
if (calcsize == NULL) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt = PyUnicode_FromString(format);
|
||||||
|
if (fmt == NULL) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = PyObject_CallFunctionObjArgs(calcsize, fmt, NULL);
|
||||||
|
if (res == NULL) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
itemsize = PyLong_AsSsize_t(res);
|
||||||
|
if (itemsize < 0) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
Py_DECREF(structmodule);
|
||||||
|
Py_XDECREF(calcsize);
|
||||||
|
Py_XDECREF(fmt);
|
||||||
|
Py_XDECREF(res);
|
||||||
|
return itemsize;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
PyBuffer_FromContiguous(Py_buffer *view, void *buf, Py_ssize_t len, char fort)
|
PyBuffer_FromContiguous(Py_buffer *view, void *buf, Py_ssize_t len, char fort)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue