bpo-41262: Convert memoryview to Argument Clinic. (GH-21421)

This commit is contained in:
Serhiy Storchaka 2020-07-18 11:12:05 +03:00 committed by GitHub
parent b4c98ed41e
commit 80a50368c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 267 additions and 74 deletions

View File

@ -2,6 +2,198 @@
preserve preserve
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(memoryview__doc__,
"memoryview(object)\n"
"--\n"
"\n"
"Create a new memoryview object which references the given object.");
static PyObject *
memoryview_impl(PyTypeObject *type, PyObject *object);
static PyObject *
memoryview(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{
PyObject *return_value = NULL;
static const char * const _keywords[] = {"object", NULL};
static _PyArg_Parser _parser = {NULL, _keywords, "memoryview", 0};
PyObject *argsbuf[1];
PyObject * const *fastargs;
Py_ssize_t nargs = PyTuple_GET_SIZE(args);
PyObject *object;
fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf);
if (!fastargs) {
goto exit;
}
object = fastargs[0];
return_value = memoryview_impl(type, object);
exit:
return return_value;
}
PyDoc_STRVAR(memoryview_release__doc__,
"release($self, /)\n"
"--\n"
"\n"
"Release the underlying buffer exposed by the memoryview object.");
#define MEMORYVIEW_RELEASE_METHODDEF \
{"release", (PyCFunction)memoryview_release, METH_NOARGS, memoryview_release__doc__},
static PyObject *
memoryview_release_impl(PyMemoryViewObject *self);
static PyObject *
memoryview_release(PyMemoryViewObject *self, PyObject *Py_UNUSED(ignored))
{
return memoryview_release_impl(self);
}
PyDoc_STRVAR(memoryview_cast__doc__,
"cast($self, /, format, shape=<unrepresentable>)\n"
"--\n"
"\n"
"Cast a memoryview to a new format or shape.");
#define MEMORYVIEW_CAST_METHODDEF \
{"cast", (PyCFunction)(void(*)(void))memoryview_cast, METH_FASTCALL|METH_KEYWORDS, memoryview_cast__doc__},
static PyObject *
memoryview_cast_impl(PyMemoryViewObject *self, PyObject *format,
PyObject *shape);
static PyObject *
memoryview_cast(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
PyObject *return_value = NULL;
static const char * const _keywords[] = {"format", "shape", NULL};
static _PyArg_Parser _parser = {NULL, _keywords, "cast", 0};
PyObject *argsbuf[2];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
PyObject *format;
PyObject *shape = NULL;
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf);
if (!args) {
goto exit;
}
if (!PyUnicode_Check(args[0])) {
_PyArg_BadArgument("cast", "argument 'format'", "str", args[0]);
goto exit;
}
if (PyUnicode_READY(args[0]) == -1) {
goto exit;
}
format = args[0];
if (!noptargs) {
goto skip_optional_pos;
}
shape = args[1];
skip_optional_pos:
return_value = memoryview_cast_impl(self, format, shape);
exit:
return return_value;
}
PyDoc_STRVAR(memoryview_toreadonly__doc__,
"toreadonly($self, /)\n"
"--\n"
"\n"
"Return a readonly version of the memoryview.");
#define MEMORYVIEW_TOREADONLY_METHODDEF \
{"toreadonly", (PyCFunction)memoryview_toreadonly, METH_NOARGS, memoryview_toreadonly__doc__},
static PyObject *
memoryview_toreadonly_impl(PyMemoryViewObject *self);
static PyObject *
memoryview_toreadonly(PyMemoryViewObject *self, PyObject *Py_UNUSED(ignored))
{
return memoryview_toreadonly_impl(self);
}
PyDoc_STRVAR(memoryview_tolist__doc__,
"tolist($self, /)\n"
"--\n"
"\n"
"Return the data in the buffer as a list of elements.");
#define MEMORYVIEW_TOLIST_METHODDEF \
{"tolist", (PyCFunction)memoryview_tolist, METH_NOARGS, memoryview_tolist__doc__},
static PyObject *
memoryview_tolist_impl(PyMemoryViewObject *self);
static PyObject *
memoryview_tolist(PyMemoryViewObject *self, PyObject *Py_UNUSED(ignored))
{
return memoryview_tolist_impl(self);
}
PyDoc_STRVAR(memoryview_tobytes__doc__,
"tobytes($self, /, order=\'C\')\n"
"--\n"
"\n"
"Return the data in the buffer as a byte string.\n"
"\n"
"Order can be {\'C\', \'F\', \'A\'}. When order is \'C\' or \'F\', the data of the\n"
"original array is converted to C or Fortran order. For contiguous views,\n"
"\'A\' returns an exact copy of the physical memory. In particular, in-memory\n"
"Fortran order is preserved. For non-contiguous views, the data is converted\n"
"to C first. order=None is the same as order=\'C\'.");
#define MEMORYVIEW_TOBYTES_METHODDEF \
{"tobytes", (PyCFunction)(void(*)(void))memoryview_tobytes, METH_FASTCALL|METH_KEYWORDS, memoryview_tobytes__doc__},
static PyObject *
memoryview_tobytes_impl(PyMemoryViewObject *self, const char *order);
static PyObject *
memoryview_tobytes(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
PyObject *return_value = NULL;
static const char * const _keywords[] = {"order", NULL};
static _PyArg_Parser _parser = {NULL, _keywords, "tobytes", 0};
PyObject *argsbuf[1];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
const char *order = NULL;
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
if (!args) {
goto exit;
}
if (!noptargs) {
goto skip_optional_pos;
}
if (args[0] == Py_None) {
order = NULL;
}
else if (PyUnicode_Check(args[0])) {
Py_ssize_t order_length;
order = PyUnicode_AsUTF8AndSize(args[0], &order_length);
if (order == NULL) {
goto exit;
}
if (strlen(order) != (size_t)order_length) {
PyErr_SetString(PyExc_ValueError, "embedded null character");
goto exit;
}
}
else {
_PyArg_BadArgument("tobytes", "argument 'order'", "str or None", args[0]);
goto exit;
}
skip_optional_pos:
return_value = memoryview_tobytes_impl(self, order);
exit:
return return_value;
}
PyDoc_STRVAR(memoryview_hex__doc__, PyDoc_STRVAR(memoryview_hex__doc__,
"hex($self, /, sep=<unrepresentable>, bytes_per_sep=1)\n" "hex($self, /, sep=<unrepresentable>, bytes_per_sep=1)\n"
"--\n" "--\n"
@ -66,4 +258,4 @@ skip_optional_pos:
exit: exit:
return return_value; return return_value;
} }
/*[clinic end generated code: output=91106ef704134b19 input=a9049054013a1b77]*/ /*[clinic end generated code: output=1b879bb934d18c66 input=a9049054013a1b77]*/

View File

@ -238,12 +238,6 @@ PyTypeObject _PyManagedBuffer_Type = {
#define REQ_FORMAT(flags) (flags&PyBUF_FORMAT) #define REQ_FORMAT(flags) (flags&PyBUF_FORMAT)
PyDoc_STRVAR(memory_doc,
"memoryview(object)\n--\n\
\n\
Create a new memoryview object which references the given object.");
/**************************************************************************/ /**************************************************************************/
/* Copy memoryview buffers */ /* Copy memoryview buffers */
/**************************************************************************/ /**************************************************************************/
@ -961,18 +955,20 @@ PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char order)
} }
/*[clinic input]
@classmethod
memoryview.__new__
object: object
Create a new memoryview object which references the given object.
[clinic start generated code]*/
static PyObject * static PyObject *
memory_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) memoryview_impl(PyTypeObject *type, PyObject *object)
/*[clinic end generated code: output=7de78e184ed66db8 input=f04429eb0bdf8c6e]*/
{ {
PyObject *obj; return PyMemoryView_FromObject(object);
static char *kwlist[] = {"object", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:memoryview", kwlist,
&obj)) {
return NULL;
}
return PyMemoryView_FromObject(obj);
} }
@ -1062,8 +1058,15 @@ _memory_release(PyMemoryViewObject *self)
return -1; return -1;
} }
/*[clinic input]
memoryview.release
Release the underlying buffer exposed by the memoryview object.
[clinic start generated code]*/
static PyObject * static PyObject *
memory_release(PyMemoryViewObject *self, PyObject *noargs) memoryview_release_impl(PyMemoryViewObject *self)
/*[clinic end generated code: output=d0b7e3ba95b7fcb9 input=bc71d1d51f4a52f0]*/
{ {
if (_memory_release(self) < 0) if (_memory_release(self) < 0)
return NULL; return NULL;
@ -1108,7 +1111,7 @@ memory_enter(PyObject *self, PyObject *args)
static PyObject * static PyObject *
memory_exit(PyObject *self, PyObject *args) memory_exit(PyObject *self, PyObject *args)
{ {
return memory_release((PyMemoryViewObject *)self, NULL); return memoryview_release_impl((PyMemoryViewObject *)self);
} }
@ -1352,26 +1355,25 @@ zero_in_shape(PyMemoryViewObject *mv)
All casts must result in views that will have the exact byte All casts must result in views that will have the exact byte
size of the original input. Otherwise, an error is raised. size of the original input. Otherwise, an error is raised.
*/ */
/*[clinic input]
memoryview.cast
format: unicode
shape: object = NULL
Cast a memoryview to a new format or shape.
[clinic start generated code]*/
static PyObject * static PyObject *
memory_cast(PyMemoryViewObject *self, PyObject *args, PyObject *kwds) memoryview_cast_impl(PyMemoryViewObject *self, PyObject *format,
PyObject *shape)
/*[clinic end generated code: output=bae520b3a389cbab input=138936cc9041b1a3]*/
{ {
static char *kwlist[] = {"format", "shape", NULL};
PyMemoryViewObject *mv = NULL; PyMemoryViewObject *mv = NULL;
PyObject *shape = NULL;
PyObject *format;
Py_ssize_t ndim = 1; Py_ssize_t ndim = 1;
CHECK_RELEASED(self); CHECK_RELEASED(self);
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist,
&format, &shape)) {
return NULL;
}
if (!PyUnicode_Check(format)) {
PyErr_SetString(PyExc_TypeError,
"memoryview: format argument must be a string");
return NULL;
}
if (!MV_C_CONTIGUOUS(self->flags)) { if (!MV_C_CONTIGUOUS(self->flags)) {
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
"memoryview: casts are restricted to C-contiguous views"); "memoryview: casts are restricted to C-contiguous views");
@ -1415,8 +1417,15 @@ error:
return NULL; return NULL;
} }
/*[clinic input]
memoryview.toreadonly
Return a readonly version of the memoryview.
[clinic start generated code]*/
static PyObject * static PyObject *
memory_toreadonly(PyMemoryViewObject *self, PyObject *noargs) memoryview_toreadonly_impl(PyMemoryViewObject *self)
/*[clinic end generated code: output=2c7e056f04c99e62 input=dc06d20f19ba236f]*/
{ {
CHECK_RELEASED(self); CHECK_RELEASED(self);
/* Even if self is already readonly, we still need to create a new /* Even if self is already readonly, we still need to create a new
@ -2109,13 +2118,20 @@ tolist_rec(const char *ptr, Py_ssize_t ndim, const Py_ssize_t *shape,
/* Return a list representation of the memoryview. Currently only buffers /* Return a list representation of the memoryview. Currently only buffers
with native format strings are supported. */ with native format strings are supported. */
/*[clinic input]
memoryview.tolist
Return the data in the buffer as a list of elements.
[clinic start generated code]*/
static PyObject * static PyObject *
memory_tolist(PyMemoryViewObject *mv, PyObject *noargs) memoryview_tolist_impl(PyMemoryViewObject *self)
/*[clinic end generated code: output=a6cda89214fd5a1b input=21e7d0c1860b211a]*/
{ {
const Py_buffer *view = &(mv->view); const Py_buffer *view = &self->view;
const char *fmt; const char *fmt;
CHECK_RELEASED(mv); CHECK_RELEASED(self);
fmt = adjust_fmt(view); fmt = adjust_fmt(view);
if (fmt == NULL) if (fmt == NULL)
@ -2135,21 +2151,30 @@ memory_tolist(PyMemoryViewObject *mv, PyObject *noargs)
} }
} }
/*[clinic input]
memoryview.tobytes
order: str(accept={str, NoneType}, c_default="NULL") = 'C'
Return the data in the buffer as a byte string.
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'.
[clinic start generated code]*/
static PyObject * static PyObject *
memory_tobytes(PyMemoryViewObject *self, PyObject *args, PyObject *kwds) memoryview_tobytes_impl(PyMemoryViewObject *self, const char *order)
/*[clinic end generated code: output=1288b62560a32a23 input=0efa3ddaeda573a8]*/
{ {
static char *kwlist[] = {"order", NULL};
Py_buffer *src = VIEW_ADDR(self); Py_buffer *src = VIEW_ADDR(self);
char *order = NULL;
char ord = 'C'; char ord = 'C';
PyObject *bytes; PyObject *bytes;
CHECK_RELEASED(self); CHECK_RELEASED(self);
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|z", kwlist, &order)) {
return NULL;
}
if (order) { if (order) {
if (strcmp(order, "F") == 0) { if (strcmp(order, "F") == 0) {
ord = 'F'; ord = 'F';
@ -3122,38 +3147,14 @@ static PyGetSetDef memory_getsetlist[] = {
{NULL, NULL, NULL, NULL}, {NULL, NULL, NULL, NULL},
}; };
PyDoc_STRVAR(memory_release_doc,
"release($self, /)\n--\n\
\n\
Release the underlying buffer exposed by the memoryview object.");
PyDoc_STRVAR(memory_tobytes_doc,
"tobytes($self, /, order=None)\n--\n\
\n\
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_tolist_doc,
"tolist($self, /)\n--\n\
\n\
Return the data in the buffer as a list of elements.");
PyDoc_STRVAR(memory_cast_doc,
"cast($self, /, format, *, shape)\n--\n\
\n\
Cast a memoryview to a new format or shape.");
PyDoc_STRVAR(memory_toreadonly_doc,
"toreadonly($self, /)\n--\n\
\n\
Return a readonly version of the memoryview.");
static PyMethodDef memory_methods[] = { static PyMethodDef memory_methods[] = {
{"release", (PyCFunction)memory_release, METH_NOARGS, memory_release_doc}, MEMORYVIEW_RELEASE_METHODDEF
{"tobytes", (PyCFunction)(void(*)(void))memory_tobytes, METH_VARARGS|METH_KEYWORDS, memory_tobytes_doc}, MEMORYVIEW_TOBYTES_METHODDEF
MEMORYVIEW_HEX_METHODDEF MEMORYVIEW_HEX_METHODDEF
{"tolist", (PyCFunction)memory_tolist, METH_NOARGS, memory_tolist_doc}, MEMORYVIEW_TOLIST_METHODDEF
{"cast", (PyCFunction)(void(*)(void))memory_cast, METH_VARARGS|METH_KEYWORDS, memory_cast_doc}, MEMORYVIEW_CAST_METHODDEF
{"toreadonly", (PyCFunction)memory_toreadonly, METH_NOARGS, memory_toreadonly_doc}, MEMORYVIEW_TOREADONLY_METHODDEF
{"__enter__", memory_enter, METH_NOARGS, NULL}, {"__enter__", memory_enter, METH_NOARGS, NULL},
{"__exit__", memory_exit, METH_VARARGS, NULL}, {"__exit__", memory_exit, METH_VARARGS, NULL},
{NULL, NULL} {NULL, NULL}
@ -3181,7 +3182,7 @@ PyTypeObject PyMemoryView_Type = {
0, /* tp_setattro */ 0, /* tp_setattro */
&memory_as_buffer, /* tp_as_buffer */ &memory_as_buffer, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
memory_doc, /* tp_doc */ memoryview__doc__, /* tp_doc */
(traverseproc)memory_traverse, /* tp_traverse */ (traverseproc)memory_traverse, /* tp_traverse */
(inquiry)memory_clear, /* tp_clear */ (inquiry)memory_clear, /* tp_clear */
memory_richcompare, /* tp_richcompare */ memory_richcompare, /* tp_richcompare */
@ -3198,5 +3199,5 @@ PyTypeObject PyMemoryView_Type = {
0, /* tp_dictoffset */ 0, /* tp_dictoffset */
0, /* tp_init */ 0, /* tp_init */
0, /* tp_alloc */ 0, /* tp_alloc */
memory_new, /* tp_new */ memoryview, /* tp_new */
}; };