diff -r 8feb6a5ce4c6 Modules/_struct.c --- a/Modules/_struct.c Wed Jan 25 23:33:27 2017 +0100 +++ b/Modules/_struct.c Thu Jan 26 18:26:33 2017 +0100 @@ -9,6 +9,13 @@ #include "structmember.h" #include +#include "clinic/_struct.c.h" + +/*[clinic input] +class Struct "PyObject *" "&PyStructType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=25178b51ecd4493b]*/ + static PyTypeObject PyStructType; /* The translation function for each format character is table driven */ @@ -1517,15 +1524,23 @@ fail: } -PyDoc_STRVAR(s_unpack__doc__, -"S.unpack(buffer) -> (v1, v2, ...)\n\ -\n\ -Return a tuple containing values unpacked according to the format\n\ -string S.format. The buffer's size in bytes must be S.size. See\n\ -help(struct) for more on format strings."); +/*[clinic input] +Struct.unpack + + buffer: object + / + +Return a tuple containing unpacked values. + +Unpack according to the format string Struct.format. The buffer's size +in bytes must be Struct.size. + +See help(struct) for more on format strings. +[clinic start generated code]*/ static PyObject * -s_unpack(PyObject *self, PyObject *input) +Struct_unpack(PyObject *self, PyObject *buffer) +/*[clinic end generated code: output=6e00bf1e6013275d input=b744b994a7a72fe2]*/ { Py_buffer vbuf; PyObject *result; @@ -1533,7 +1548,7 @@ s_unpack(PyObject *self, PyObject *input assert(PyStruct_Check(self)); assert(soself->s_codes != NULL); - if (PyObject_GetBuffer(input, &vbuf, PyBUF_SIMPLE) < 0) + if (PyObject_GetBuffer(buffer, &vbuf, PyBUF_SIMPLE) < 0) return NULL; if (vbuf.len != soself->s_size) { PyErr_Format(StructError, @@ -1547,20 +1562,9 @@ s_unpack(PyObject *self, PyObject *input return result; } -PyDoc_STRVAR(s_unpack_from__doc__, -"S.unpack_from(buffer, offset=0) -> (v1, v2, ...)\n\ -\n\ -Return a tuple containing values unpacked according to the format\n\ -string S.format. The buffer's size in bytes, minus offset, must be at\n\ -least S.size. See help(struct) for more on format strings."); - static PyObject * -s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds) +s_unpack_from_impl(PyObject *self, PyObject *input, Py_ssize_t offset) { - static char *kwlist[] = {"buffer", "offset", 0}; - - PyObject *input; - Py_ssize_t offset = 0; Py_buffer vbuf; PyObject *result; PyStructObject *soself = (PyStructObject *)self; @@ -1568,10 +1572,6 @@ s_unpack_from(PyObject *self, PyObject * assert(PyStruct_Check(self)); assert(soself->s_codes != NULL); - if (!PyArg_ParseTupleAndKeywords(args, kwds, - "O|n:unpack_from", kwlist, - &input, &offset)) - return NULL; if (PyObject_GetBuffer(input, &vbuf, PyBUF_SIMPLE) < 0) return NULL; if (offset < 0) @@ -1588,6 +1588,28 @@ s_unpack_from(PyObject *self, PyObject * return result; } +/*[clinic input] +Struct.unpack_from + + buffer: object + offset: Py_ssize_t = 0 + +Return a tuple containing unpacked values. + +Values are unpacked according to the format string Struct.format. + +The buffer's size in bytes, minus offset, must be at least Struct.size. + +See help(struct) for more on format strings. +[clinic start generated code]*/ + +static PyObject * +Struct_unpack_from_impl(PyObject *self, PyObject *buffer, Py_ssize_t offset) +/*[clinic end generated code: output=f1d2128f09ba6048 input=893bfb6d67124b16]*/ +{ + return s_unpack_from_impl(self, buffer, offset); +} + /* Unpack iterator type */ @@ -1680,15 +1702,8 @@ static PyTypeObject unpackiter_type = { unpackiter_methods /* tp_methods */ }; -PyDoc_STRVAR(s_iter_unpack__doc__, -"S.iter_unpack(buffer) -> iterator(v1, v2, ...)\n\ -\n\ -Return an iterator yielding tuples unpacked from the given bytes\n\ -source, like a repeated invocation of unpack_from(). Requires\n\ -that the bytes length be a multiple of the struct size."); - static PyObject * -s_iter_unpack(PyObject *_so, PyObject *input) +s_iter_unpack_impl(PyObject *_so, PyObject *input) { PyStructObject *so = (PyStructObject *) _so; unpackiterobject *self; @@ -1724,6 +1739,27 @@ s_iter_unpack(PyObject *_so, PyObject *i return (PyObject *) self; } +/*[clinic input] +Struct.iter_unpack + + input: object + / + +Return an iterator yielding tuples. + +Tuples are unpacked from the given bytes source, like a repeated +invocation of unpack_from(). + +Requires that the bytes length be a multiple of the struct size. +[clinic start generated code]*/ + +static PyObject * +Struct_iter_unpack(PyObject *self, PyObject *input) +/*[clinic end generated code: output=604cde237e54c45a input=41455b6a903762dc]*/ +{ + return s_iter_unpack_impl(self, input); +} + /* * Guts of the pack function. @@ -1736,7 +1772,7 @@ s_iter_unpack(PyObject *_so, PyObject *i * */ static int -s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf) +s_pack_internal(PyStructObject *soself, PyObject **args, int offset, char* buf) { formatcode *code; /* XXX(nnorwitz): why does i need to be a local? can we use @@ -1750,7 +1786,7 @@ s_pack_internal(PyStructObject *soself, char *res = buf + code->offset; Py_ssize_t j = code->repeat; while (j--) { - PyObject *v = PyTuple_GET_ITEM(args, i++); + PyObject *v = args[i++]; if (e->format == 's') { Py_ssize_t n; int isstring; @@ -1823,7 +1859,7 @@ to the format string S.format. See help strings."); static PyObject * -s_pack(PyObject *self, PyObject *args) +s_pack(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) { PyStructObject *soself; PyObject *result; @@ -1832,10 +1868,13 @@ s_pack(PyObject *self, PyObject *args) soself = (PyStructObject *)self; assert(PyStruct_Check(self)); assert(soself->s_codes != NULL); - if (PyTuple_GET_SIZE(args) != soself->s_len) + if (nargs != soself->s_len) { PyErr_Format(StructError, - "pack expected %zd items for packing (got %zd)", soself->s_len, PyTuple_GET_SIZE(args)); + "pack expected %zd items for packing (got %zd)", soself->s_len, nargs); + return NULL; + } + if (!_PyArg_NoStackKeywords("pack", kwnames)) { return NULL; } @@ -1862,7 +1901,7 @@ offset. Note that the offset is a requi help(struct) for more on format strings."); static PyObject * -s_pack_into(PyObject *self, PyObject *args) +s_pack_into(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) { PyStructObject *soself; Py_buffer buffer; @@ -1872,31 +1911,34 @@ s_pack_into(PyObject *self, PyObject *ar soself = (PyStructObject *)self; assert(PyStruct_Check(self)); assert(soself->s_codes != NULL); - if (PyTuple_GET_SIZE(args) != (soself->s_len + 2)) + if (nargs != (soself->s_len + 2)) { - if (PyTuple_GET_SIZE(args) == 0) { + if (nargs == 0) { PyErr_Format(StructError, "pack_into expected buffer argument"); } - else if (PyTuple_GET_SIZE(args) == 1) { + else if (nargs == 1) { PyErr_Format(StructError, "pack_into expected offset argument"); } else { PyErr_Format(StructError, "pack_into expected %zd items for packing (got %zd)", - soself->s_len, (PyTuple_GET_SIZE(args) - 2)); + soself->s_len, (nargs - 2)); } return NULL; } + if (!_PyArg_NoStackKeywords("pack_into", kwnames)) { + return NULL; + } /* Extract a writable memory buffer from the first argument */ - if (!PyArg_Parse(PyTuple_GET_ITEM(args, 0), "w*", &buffer)) + if (!PyArg_Parse(args[0], "w*", &buffer)) return NULL; assert(buffer.len >= 0); /* Extract the offset from the first argument */ - offset = PyNumber_AsSsize_t(PyTuple_GET_ITEM(args, 1), PyExc_IndexError); + offset = PyNumber_AsSsize_t(args[1], PyExc_IndexError); if (offset == -1 && PyErr_Occurred()) { PyBuffer_Release(&buffer); return NULL; @@ -1956,12 +1998,11 @@ s_sizeof(PyStructObject *self, void *unu /* List of functions */ static struct PyMethodDef s_methods[] = { - {"iter_unpack", s_iter_unpack, METH_O, s_iter_unpack__doc__}, - {"pack", s_pack, METH_VARARGS, s_pack__doc__}, - {"pack_into", s_pack_into, METH_VARARGS, s_pack_into__doc__}, - {"unpack", s_unpack, METH_O, s_unpack__doc__}, - {"unpack_from", (PyCFunction)s_unpack_from, METH_VARARGS|METH_KEYWORDS, - s_unpack_from__doc__}, + STRUCT_ITER_UNPACK_METHODDEF + {"pack", (PyCFunction)s_pack, METH_FASTCALL, s_pack__doc__}, + {"pack_into", (PyCFunction)s_pack_into, METH_FASTCALL, s_pack_into__doc__}, + STRUCT_UNPACK_METHODDEF + STRUCT_UNPACK_FROM_METHODDEF {"__sizeof__", (PyCFunction)s_sizeof, METH_NOARGS, s_sizeof__doc__}, {NULL, NULL} /* sentinel */ }; @@ -2057,23 +2098,32 @@ cache_struct(PyObject *fmt) return s_object; } -PyDoc_STRVAR(clearcache_doc, -"Clear the internal cache."); +/*[clinic input] +_clearcache + +Clear the internal cache. +[clinic start generated code]*/ static PyObject * -clearcache(PyObject *self) +_clearcache_impl(PyObject *module) +/*[clinic end generated code: output=ce4fb8a7bf7cb523 input=463eaae04bab3211]*/ { Py_CLEAR(cache); Py_RETURN_NONE; } -PyDoc_STRVAR(calcsize_doc, -"calcsize(fmt) -> integer\n\ -\n\ -Return size in bytes of the struct described by the format string fmt."); + +/*[clinic input] +calcsize + + fmt: object + +Return size in bytes of the struct described by the format string fmt. +[clinic start generated code]*/ static PyObject * -calcsize(PyObject *self, PyObject *fmt) +calcsize_impl(PyObject *module, PyObject *fmt) +/*[clinic end generated code: output=f59c8b987f14669a input=ce28e6aadb40d636]*/ { Py_ssize_t n; PyObject *s_object = cache_struct(fmt); @@ -2091,27 +2141,21 @@ Return a bytes object containing the val to the format string fmt. See help(struct) for more on format strings."); static PyObject * -pack(PyObject *self, PyObject *args) +pack(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *s_object, *fmt, *newargs, *result; - Py_ssize_t n = PyTuple_GET_SIZE(args); + PyObject *s_object, *fmt, *result; - if (n == 0) { + if (nargs == 0) { PyErr_SetString(PyExc_TypeError, "missing format argument"); return NULL; } - fmt = PyTuple_GET_ITEM(args, 0); - newargs = PyTuple_GetSlice(args, 1, n); - if (newargs == NULL) - return NULL; + fmt = args[0]; s_object = cache_struct(fmt); if (s_object == NULL) { - Py_DECREF(newargs); return NULL; } - result = s_pack(s_object, newargs); - Py_DECREF(newargs); + result = s_pack(s_object, args + 1, nargs - 1, kwnames); Py_DECREF(s_object); return result; } @@ -2125,120 +2169,122 @@ that the offset is a required argument. on format strings."); static PyObject * -pack_into(PyObject *self, PyObject *args) +pack_into(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *s_object, *fmt, *newargs, *result; - Py_ssize_t n = PyTuple_GET_SIZE(args); + PyObject *s_object, *fmt, *result; - if (n == 0) { + if (nargs == 0) { PyErr_SetString(PyExc_TypeError, "missing format argument"); return NULL; } - fmt = PyTuple_GET_ITEM(args, 0); - newargs = PyTuple_GetSlice(args, 1, n); - if (newargs == NULL) - return NULL; + fmt = args[0]; s_object = cache_struct(fmt); if (s_object == NULL) { - Py_DECREF(newargs); return NULL; } - result = s_pack_into(s_object, newargs); - Py_DECREF(newargs); - Py_DECREF(s_object); - return result; -} - -PyDoc_STRVAR(unpack_doc, -"unpack(fmt, buffer) -> (v1, v2, ...)\n\ -\n\ -Return a tuple containing values unpacked according to the format string\n\ -fmt. The buffer's size in bytes must be calcsize(fmt). See help(struct)\n\ -for more on format strings."); - -static PyObject * -unpack(PyObject *self, PyObject *args) -{ - PyObject *s_object, *fmt, *inputstr, *result; - - if (!PyArg_UnpackTuple(args, "unpack", 2, 2, &fmt, &inputstr)) - return NULL; - - s_object = cache_struct(fmt); - if (s_object == NULL) - return NULL; - result = s_unpack(s_object, inputstr); + result = s_pack_into(s_object, args + 1, nargs - 1, kwnames); Py_DECREF(s_object); return result; } -PyDoc_STRVAR(unpack_from_doc, -"unpack_from(fmt, buffer, offset=0) -> (v1, v2, ...)\n\ -\n\ -Return a tuple containing values unpacked according to the format string\n\ -fmt. The buffer's size, minus offset, must be at least calcsize(fmt).\n\ -See help(struct) for more on format strings."); +/*[clinic input] +unpack + + fmt: object + inputstr: object + / + +Return a tuple containing values unpacked according to the format string fmt. + +The buffer's size in bytes must be calcsize(fmt). + +See help(struct) for more on format strings. +[clinic start generated code]*/ static PyObject * -unpack_from(PyObject *self, PyObject *args, PyObject *kwds) +unpack_impl(PyObject *module, PyObject *fmt, PyObject *inputstr) +/*[clinic end generated code: output=66ff65ed7e289828 input=684dceeeb0f3701d]*/ { - PyObject *s_object, *fmt, *newargs, *result; - Py_ssize_t n = PyTuple_GET_SIZE(args); - - if (n == 0) { - PyErr_SetString(PyExc_TypeError, "missing format argument"); - return NULL; - } - fmt = PyTuple_GET_ITEM(args, 0); - newargs = PyTuple_GetSlice(args, 1, n); - if (newargs == NULL) - return NULL; + PyObject *s_object, *result; s_object = cache_struct(fmt); - if (s_object == NULL) { - Py_DECREF(newargs); + if (s_object == NULL) return NULL; - } - result = s_unpack_from(s_object, newargs, kwds); - Py_DECREF(newargs); + result = Struct_unpack(s_object, inputstr); Py_DECREF(s_object); return result; } -PyDoc_STRVAR(iter_unpack_doc, -"iter_unpack(fmt, buffer) -> iterator(v1, v2, ...)\n\ -\n\ -Return an iterator yielding tuples unpacked from the given bytes\n\ -source according to the format string, like a repeated invocation of\n\ -unpack_from(). Requires that the bytes length be a multiple of the\n\ -format struct size."); +/*[clinic input] +unpack_from + + fmt: object + buffer: object + offset: Py_ssize_t = 0 + +Return a tuple containing values unpacked according to the format string fmt. + +The buffer's size, minus offset, must be at least calcsize(fmt). + +See help(struct) for more on format strings. +[clinic start generated code]*/ static PyObject * -iter_unpack(PyObject *self, PyObject *args) +unpack_from_impl(PyObject *module, PyObject *fmt, PyObject *buffer, + Py_ssize_t offset) +/*[clinic end generated code: output=575400735ad4db48 input=a64bca1adce5484e]*/ { - PyObject *s_object, *fmt, *input, *result; + PyObject *s_object, *result; - if (!PyArg_ParseTuple(args, "OO:iter_unpack", &fmt, &input)) + s_object = cache_struct(fmt); + if (s_object == NULL) { return NULL; + } + result = s_unpack_from_impl(s_object, buffer, offset); + + Py_DECREF(s_object); + return result; +} + +/*[clinic input] +iter_unpack + + fmt: object + buffer: object + / + +Return an iterator yielding tuples unpacked from the given bytes. + +The bytes are unpacked according to the format string, like +a repeated invocation of unpack_from(). + +Requires that the bytes length be a multiple of the format struct size. +[clinic start generated code]*/ + +static PyObject * +iter_unpack_impl(PyObject *module, PyObject *fmt, PyObject *buffer) +/*[clinic end generated code: output=27470d5a603262d3 input=3178987b9c9e2cfc]*/ +{ + PyObject *s_object, *result; s_object = cache_struct(fmt); if (s_object == NULL) return NULL; - result = s_iter_unpack(s_object, input); + + result = s_iter_unpack_impl(s_object, buffer); Py_DECREF(s_object); return result; } static struct PyMethodDef module_functions[] = { - {"_clearcache", (PyCFunction)clearcache, METH_NOARGS, clearcache_doc}, - {"calcsize", calcsize, METH_O, calcsize_doc}, - {"iter_unpack", iter_unpack, METH_VARARGS, iter_unpack_doc}, - {"pack", pack, METH_VARARGS, pack_doc}, - {"pack_into", pack_into, METH_VARARGS, pack_into_doc}, - {"unpack", unpack, METH_VARARGS, unpack_doc}, - {"unpack_from", (PyCFunction)unpack_from, - METH_VARARGS|METH_KEYWORDS, unpack_from_doc}, + _CLEARCACHE_METHODDEF + CALCSIZE_METHODDEF + ITER_UNPACK_METHODDEF + {"pack", (PyCFunction)pack, METH_FASTCALL, pack_doc}, + {"pack_into", (PyCFunction)pack_into, METH_FASTCALL, pack_into_doc}, + UNPACK_METHODDEF + UNPACK_FROM_METHODDEF {NULL, NULL} /* sentinel */ }; diff -r 8feb6a5ce4c6 Modules/clinic/_struct.c.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modules/clinic/_struct.c.h Thu Jan 26 18:26:33 2017 +0100 @@ -0,0 +1,231 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(Struct_unpack__doc__, +"unpack($self, buffer, /)\n" +"--\n" +"\n" +"Return a tuple containing unpacked values.\n" +"\n" +"Unpack according to the format string Struct.format. The buffer\'s size\n" +"in bytes must be Struct.size.\n" +"\n" +"See help(struct) for more on format strings."); + +#define STRUCT_UNPACK_METHODDEF \ + {"unpack", (PyCFunction)Struct_unpack, METH_O, Struct_unpack__doc__}, + +PyDoc_STRVAR(Struct_unpack_from__doc__, +"unpack_from($self, /, buffer, offset=0)\n" +"--\n" +"\n" +"Return a tuple containing unpacked values.\n" +"\n" +"Values are unpacked according to the format string Struct.format.\n" +"\n" +"The buffer\'s size in bytes, minus offset, must be at least Struct.size.\n" +"\n" +"See help(struct) for more on format strings."); + +#define STRUCT_UNPACK_FROM_METHODDEF \ + {"unpack_from", (PyCFunction)Struct_unpack_from, METH_FASTCALL, Struct_unpack_from__doc__}, + +static PyObject * +Struct_unpack_from_impl(PyObject *self, PyObject *buffer, Py_ssize_t offset); + +static PyObject * +Struct_unpack_from(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"buffer", "offset", NULL}; + static _PyArg_Parser _parser = {"O|n:unpack_from", _keywords, 0}; + PyObject *buffer; + Py_ssize_t offset = 0; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &buffer, &offset)) { + goto exit; + } + return_value = Struct_unpack_from_impl(self, buffer, offset); + +exit: + return return_value; +} + +PyDoc_STRVAR(Struct_iter_unpack__doc__, +"iter_unpack($self, input, /)\n" +"--\n" +"\n" +"Return an iterator yielding tuples.\n" +"\n" +"Tuples are unpacked from the given bytes source, like a repeated\n" +"invocation of unpack_from().\n" +"\n" +"Requires that the bytes length be a multiple of the struct size."); + +#define STRUCT_ITER_UNPACK_METHODDEF \ + {"iter_unpack", (PyCFunction)Struct_iter_unpack, METH_O, Struct_iter_unpack__doc__}, + +PyDoc_STRVAR(_clearcache__doc__, +"_clearcache($module, /)\n" +"--\n" +"\n" +"Clear the internal cache."); + +#define _CLEARCACHE_METHODDEF \ + {"_clearcache", (PyCFunction)_clearcache, METH_NOARGS, _clearcache__doc__}, + +static PyObject * +_clearcache_impl(PyObject *module); + +static PyObject * +_clearcache(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _clearcache_impl(module); +} + +PyDoc_STRVAR(calcsize__doc__, +"calcsize($module, /, fmt)\n" +"--\n" +"\n" +"Return size in bytes of the struct described by the format string fmt."); + +#define CALCSIZE_METHODDEF \ + {"calcsize", (PyCFunction)calcsize, METH_FASTCALL, calcsize__doc__}, + +static PyObject * +calcsize_impl(PyObject *module, PyObject *fmt); + +static PyObject * +calcsize(PyObject *module, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"fmt", NULL}; + static _PyArg_Parser _parser = {"O:calcsize", _keywords, 0}; + PyObject *fmt; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &fmt)) { + goto exit; + } + return_value = calcsize_impl(module, fmt); + +exit: + return return_value; +} + +PyDoc_STRVAR(unpack__doc__, +"unpack($module, fmt, inputstr, /)\n" +"--\n" +"\n" +"Return a tuple containing values unpacked according to the format string fmt.\n" +"\n" +"The buffer\'s size in bytes must be calcsize(fmt).\n" +"\n" +"See help(struct) for more on format strings."); + +#define UNPACK_METHODDEF \ + {"unpack", (PyCFunction)unpack, METH_FASTCALL, unpack__doc__}, + +static PyObject * +unpack_impl(PyObject *module, PyObject *fmt, PyObject *inputstr); + +static PyObject * +unpack(PyObject *module, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + PyObject *fmt; + PyObject *inputstr; + + if (!_PyArg_UnpackStack(args, nargs, "unpack", + 2, 2, + &fmt, &inputstr)) { + goto exit; + } + + if (!_PyArg_NoStackKeywords("unpack", kwnames)) { + goto exit; + } + return_value = unpack_impl(module, fmt, inputstr); + +exit: + return return_value; +} + +PyDoc_STRVAR(unpack_from__doc__, +"unpack_from($module, /, fmt, buffer, offset=0)\n" +"--\n" +"\n" +"Return a tuple containing values unpacked according to the format string fmt.\n" +"\n" +"The buffer\'s size, minus offset, must be at least calcsize(fmt).\n" +"\n" +"See help(struct) for more on format strings."); + +#define UNPACK_FROM_METHODDEF \ + {"unpack_from", (PyCFunction)unpack_from, METH_FASTCALL, unpack_from__doc__}, + +static PyObject * +unpack_from_impl(PyObject *module, PyObject *fmt, PyObject *buffer, + Py_ssize_t offset); + +static PyObject * +unpack_from(PyObject *module, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"fmt", "buffer", "offset", NULL}; + static _PyArg_Parser _parser = {"OO|n:unpack_from", _keywords, 0}; + PyObject *fmt; + PyObject *buffer; + Py_ssize_t offset = 0; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &fmt, &buffer, &offset)) { + goto exit; + } + return_value = unpack_from_impl(module, fmt, buffer, offset); + +exit: + return return_value; +} + +PyDoc_STRVAR(iter_unpack__doc__, +"iter_unpack($module, fmt, buffer, /)\n" +"--\n" +"\n" +"Return an iterator yielding tuples unpacked from the given bytes.\n" +"\n" +"The bytes are unpacked according to the format string, like\n" +"a repeated invocation of unpack_from().\n" +"\n" +"Requires that the bytes length be a multiple of the format struct size."); + +#define ITER_UNPACK_METHODDEF \ + {"iter_unpack", (PyCFunction)iter_unpack, METH_FASTCALL, iter_unpack__doc__}, + +static PyObject * +iter_unpack_impl(PyObject *module, PyObject *fmt, PyObject *buffer); + +static PyObject * +iter_unpack(PyObject *module, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + PyObject *fmt; + PyObject *buffer; + + if (!_PyArg_UnpackStack(args, nargs, "iter_unpack", + 2, 2, + &fmt, &buffer)) { + goto exit; + } + + if (!_PyArg_NoStackKeywords("iter_unpack", kwnames)) { + goto exit; + } + return_value = iter_unpack_impl(module, fmt, buffer); + +exit: + return return_value; +} +/*[clinic end generated code: output=84f21b5617c5de0c input=a9049054013a1b77]*/