: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`.
- 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)
/* Return the implied itemsize of the data-format area from a
struct-style description. */
-PyAPI_FUNC(int) PyBuffer_SizeFromFormat(const char *);
+PyAPI_FUNC(Py_ssize_t) PyBuffer_SizeFromFormat(const char *format);
/* Implementation in memoryobject.c */
PyAPI_FUNC(int) PyBuffer_ToContiguous(void *buf, Py_buffer *view,
except ImportError:
numpy_array = None
+try:
+ import _testcapi
+except ImportError:
+ _testcapi = None
+
SHORT_TEST = True
x = ndarray([1,2,3], shape=[3], flags=ND_GETBUF_FAIL)
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__":
unittest.main()
--- /dev/null
+Implement :c:func:`PyBuffer_SizeFromFormat()` function (previously
+documented but not implemented): call :func:`struct.calcsize`.
+Patch by Joannah Nanjekye.
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
cause an infinite loop. Run via Lib/test/test_capi.py */
static PyObject *
{"test_pep3118_obsolete_write_locks", (PyCFunction)test_pep3118_obsolete_write_locks, METH_NOARGS},
#endif
{"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},
{"get_args", get_args, METH_VARARGS},
{"get_kwargs", (PyCFunction)(void(*)(void))get_kwargs, METH_VARARGS|METH_KEYWORDS},
}
}
+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
PyBuffer_FromContiguous(Py_buffer *view, void *buf, Py_ssize_t len, char fort)
{