gh-143672: Finish conversion of the struct module to Argument Clinic (GH-143857)

Co-authored-by: Sergey B Kirpichev <skirpichev@gmail.com>
This commit is contained in:
Serhiy Storchaka 2026-01-16 13:35:23 +02:00 committed by GitHub
parent 66680f1230
commit 780e9692fe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 350 additions and 194 deletions

View File

@ -6266,6 +6266,10 @@ class TestSignatureDefinitions(unittest.TestCase):
import stat
self._test_module_has_signatures(stat)
def test_struct_module_has_signatures(self):
import struct
self._test_module_has_signatures(struct)
def test_string_module_has_signatures(self):
import string
self._test_module_has_signatures(string)

View File

@ -1784,15 +1784,13 @@ Struct.__init__
Create a compiled struct object.
Return a new Struct object which writes and reads binary data according to
the format string.
See help(struct) for more on format strings.
Return a new Struct object which writes and reads binary data according
to the format string. See help(struct) for more on format strings.
[clinic start generated code]*/
static int
Struct___init___impl(PyStructObject *self, PyObject *format)
/*[clinic end generated code: output=b8e80862444e92d0 input=192a4575a3dde802]*/
/*[clinic end generated code: output=b8e80862444e92d0 input=1af78a5f57d82cec]*/
{
int ret = 0;
@ -1914,15 +1912,14 @@ Struct.unpack
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.
Unpack according to the struct format string. The buffer's
size in bytes must be the struct size. See help(struct) for more on
format strings.
[clinic start generated code]*/
static PyObject *
Struct_unpack_impl(PyStructObject *self, Py_buffer *buffer)
/*[clinic end generated code: output=873a24faf02e848a input=3113f8e7038b2f6c]*/
/*[clinic end generated code: output=873a24faf02e848a input=488843a57c47065a]*/
{
_structmodulestate *state = get_struct_state_structinst(self);
ENSURE_STRUCT_IS_READY(self);
@ -1943,18 +1940,16 @@ Struct.unpack_from
Return a tuple containing unpacked values.
Values are unpacked according to the format string Struct.format.
The buffer's size in bytes, starting at position offset, must be
at least Struct.size.
See help(struct) for more on format strings.
Values are unpacked according to the struct format string. The
buffer's size in bytes, starting at position offset, must be at
least the struct size. See help(struct) for more on format
strings.
[clinic start generated code]*/
static PyObject *
Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer,
Py_ssize_t offset)
/*[clinic end generated code: output=57fac875e0977316 input=cafd4851d473c894]*/
/*[clinic end generated code: output=57fac875e0977316 input=57cfcf84c088faa4]*/
{
_structmodulestate *state = get_struct_state_structinst(self);
ENSURE_STRUCT_IS_READY(self);
@ -2098,14 +2093,13 @@ Struct.iter_unpack
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.
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_impl(PyStructObject *self, PyObject *buffer)
/*[clinic end generated code: output=818f89ad4afa8d64 input=6d65b3f3107dbc99]*/
/*[clinic end generated code: output=818f89ad4afa8d64 input=9555d2d29d1d9cd2]*/
{
_structmodulestate *state = get_struct_state_structinst(self);
unpackiterobject *iter;
@ -2150,7 +2144,7 @@ Struct_iter_unpack_impl(PyStructObject *self, PyObject *buffer)
*
*/
static int
s_pack_internal(PyStructObject *soself, PyObject *const *args, int offset,
s_pack_internal(PyStructObject *soself, PyObject *const *args,
char* buf, _structmodulestate *state)
{
formatcode *code;
@ -2159,7 +2153,7 @@ s_pack_internal(PyStructObject *soself, PyObject *const *args, int offset,
Py_ssize_t i;
memset(buf, '\0', soself->s_size);
i = offset;
i = 0;
for (code = soself->s_codes; code->fmtdef != NULL; code++) {
const formatdef *e = code->fmtdef;
char *res = buf + code->offset;
@ -2234,145 +2228,132 @@ s_pack_internal(PyStructObject *soself, PyObject *const *args, int offset,
}
PyDoc_STRVAR(s_pack__doc__,
"S.pack(v1, v2, ...) -> bytes\n\
\n\
Return a bytes object containing values v1, v2, ... packed according\n\
to the format string S.format. See help(struct) for more on format\n\
strings.");
/*[clinic input]
Struct.pack
*values: array
Pack values and return the packed bytes.
Return a bytes object containing the provided values packed
according to the struct format string. See help(struct) for more on
format strings.
[clinic start generated code]*/
static PyObject *
s_pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
Struct_pack_impl(PyStructObject *self, PyObject * const *values,
Py_ssize_t values_length)
/*[clinic end generated code: output=5766e18f596cae9e input=295f4b1a97747458]*/
{
PyStructObject *soself;
_structmodulestate *state = get_struct_state_structinst(self);
/* Validate arguments. */
soself = PyStructObject_CAST(self);
ENSURE_STRUCT_IS_READY(soself);
assert(PyStruct_Check(self, state));
if (nargs != soself->s_len)
{
ENSURE_STRUCT_IS_READY(self);
if (values_length != self->s_len) {
PyErr_Format(state->StructError,
"pack expected %zd items for packing (got %zd)", soself->s_len, nargs);
"pack expected %zd items for packing (got %zd)",
self->s_len, values_length);
return NULL;
}
/* Allocate a new string */
PyBytesWriter *writer = PyBytesWriter_Create(soself->s_size);
PyBytesWriter *writer = PyBytesWriter_Create(self->s_size);
if (writer == NULL) {
return NULL;
}
char *buf = PyBytesWriter_GetData(writer);
/* Call the guts */
if ( s_pack_internal(soself, args, 0, buf, state) != 0 ) {
if (s_pack_internal(self, values, buf, state) != 0) {
PyBytesWriter_Discard(writer);
return NULL;
}
return PyBytesWriter_FinishWithSize(writer, soself->s_size);
return PyBytesWriter_FinishWithSize(writer, self->s_size);
}
PyDoc_STRVAR(s_pack_into__doc__,
"S.pack_into(buffer, offset, v1, v2, ...)\n\
\n\
Pack the values v1, v2, ... according to the format string S.format\n\
and write the packed bytes into the writable buffer buf starting at\n\
offset. Note that the offset is a required argument. See\n\
help(struct) for more on format strings.");
/*[clinic input]
Struct.pack_into
buffer: Py_buffer(accept={rwbuffer})
offset as offset_obj: object
/
*values: array
Pack values and write the packed bytes into the buffer.
Pack the provided values according to the struct format string
and write the packed bytes into the writable buffer starting at
offset. Note that the offset is a required argument. See
help(struct) for more on format strings.
[clinic start generated code]*/
static PyObject *
s_pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
Struct_pack_into_impl(PyStructObject *self, Py_buffer *buffer,
PyObject *offset_obj, PyObject * const *values,
Py_ssize_t values_length)
/*[clinic end generated code: output=b0c2ef496135dad3 input=d0de9b9f138c782d]*/
{
PyStructObject *soself;
Py_buffer buffer;
Py_ssize_t offset;
_structmodulestate *state = get_struct_state_structinst(self);
/* Validate arguments. +1 is for the first arg as buffer. */
soself = PyStructObject_CAST(self);
ENSURE_STRUCT_IS_READY(soself);
assert(PyStruct_Check(self, state));
if (nargs != (soself->s_len + 2))
{
if (nargs == 0) {
PyErr_Format(state->StructError,
"pack_into expected buffer argument");
}
else if (nargs == 1) {
PyErr_Format(state->StructError,
"pack_into expected offset argument");
}
else {
PyErr_Format(state->StructError,
"pack_into expected %zd items for packing (got %zd)",
soself->s_len, (nargs - 2));
}
ENSURE_STRUCT_IS_READY(self);
if (values_length != self->s_len) {
PyErr_Format(state->StructError,
"pack_into expected %zd items for packing (got %zd)",
self->s_len, values_length);
return NULL;
}
/* Extract a writable memory buffer from the first argument */
if (!PyArg_Parse(args[0], "w*", &buffer))
return NULL;
assert(buffer.len >= 0);
/* Extract the offset from the first argument */
offset = PyNumber_AsSsize_t(args[1], PyExc_IndexError);
offset = PyNumber_AsSsize_t(offset_obj, PyExc_IndexError);
if (offset == -1 && PyErr_Occurred()) {
PyBuffer_Release(&buffer);
return NULL;
}
/* Support negative offsets. */
if (offset < 0) {
/* Check that negative offset is low enough to fit data */
if (offset + soself->s_size > 0) {
if (offset + self->s_size > 0) {
PyErr_Format(state->StructError,
"no space to pack %zd bytes at offset %zd",
soself->s_size,
self->s_size,
offset);
PyBuffer_Release(&buffer);
return NULL;
}
/* Check that negative offset is not crossing buffer boundary */
if (offset + buffer.len < 0) {
if (offset + buffer->len < 0) {
PyErr_Format(state->StructError,
"offset %zd out of range for %zd-byte buffer",
offset,
buffer.len);
PyBuffer_Release(&buffer);
buffer->len);
return NULL;
}
offset += buffer.len;
offset += buffer->len;
}
/* Check boundaries */
if ((buffer.len - offset) < soself->s_size) {
if ((buffer->len - offset) < self->s_size) {
assert(offset >= 0);
assert(soself->s_size >= 0);
assert(self->s_size >= 0);
PyErr_Format(state->StructError,
"pack_into requires a buffer of at least %zu bytes for "
"packing %zd bytes at offset %zd "
"(actual buffer size is %zd)",
(size_t)soself->s_size + (size_t)offset,
soself->s_size,
(size_t)self->s_size + (size_t)offset,
self->s_size,
offset,
buffer.len);
PyBuffer_Release(&buffer);
buffer->len);
return NULL;
}
/* Call the guts */
if (s_pack_internal(soself, args, 2, (char*)buffer.buf + offset, state) != 0) {
PyBuffer_Release(&buffer);
if (s_pack_internal(self, values, (char*)buffer->buf + offset, state) != 0) {
return NULL;
}
PyBuffer_Release(&buffer);
Py_RETURN_NONE;
}
@ -2392,13 +2373,14 @@ s_get_size(PyObject *op, void *Py_UNUSED(closure))
return PyLong_FromSsize_t(self->s_size);
}
PyDoc_STRVAR(s_sizeof__doc__,
"S.__sizeof__() -> size of S in memory, in bytes");
/*[clinic input]
Struct.__sizeof__
[clinic start generated code]*/
static PyObject *
s_sizeof(PyObject *op, PyObject *Py_UNUSED(dummy))
Struct___sizeof___impl(PyStructObject *self)
/*[clinic end generated code: output=2d0d78900b4cdb4e input=faca5925c1f1ffd0]*/
{
PyStructObject *self = PyStructObject_CAST(op);
size_t size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode);
for (formatcode *code = self->s_codes; code->fmtdef != NULL; code++) {
size += sizeof(formatcode);
@ -2424,11 +2406,11 @@ s_repr(PyObject *op)
static struct PyMethodDef s_methods[] = {
STRUCT_ITER_UNPACK_METHODDEF
{"pack", _PyCFunction_CAST(s_pack), METH_FASTCALL, s_pack__doc__},
{"pack_into", _PyCFunction_CAST(s_pack_into), METH_FASTCALL, s_pack_into__doc__},
STRUCT_PACK_METHODDEF
STRUCT_PACK_INTO_METHODDEF
STRUCT_UNPACK_METHODDEF
STRUCT_UNPACK_FROM_METHODDEF
{"__sizeof__", s_sizeof, METH_NOARGS, s_sizeof__doc__},
STRUCT___SIZEOF___METHODDEF
{NULL, NULL} /* sentinel */
};
@ -2443,17 +2425,12 @@ static PyGetSetDef s_getsetlist[] = {
{NULL} /* sentinel */
};
PyDoc_STRVAR(s__doc__,
"Struct(fmt) --> compiled struct object\n"
"\n"
);
static PyType_Slot PyStructType_slots[] = {
{Py_tp_dealloc, s_dealloc},
{Py_tp_getattro, PyObject_GenericGetAttr},
{Py_tp_setattro, PyObject_GenericSetAttr},
{Py_tp_repr, s_repr},
{Py_tp_doc, (void*)s__doc__},
{Py_tp_doc, (void*)Struct___init____doc__},
{Py_tp_traverse, s_traverse},
{Py_tp_clear, s_clear},
{Py_tp_methods, s_methods},
@ -2543,58 +2520,52 @@ calcsize_impl(PyObject *module, PyStructObject *s_object)
return s_object->s_size;
}
PyDoc_STRVAR(pack_doc,
"pack(format, v1, v2, ...) -> bytes\n\
\n\
Return a bytes object containing the values v1, v2, ... packed according\n\
to the format string. See help(struct) for more on format strings.");
/*[clinic input]
pack
format as s_object: cache_struct
/
*values: array
Pack values and return the packed bytes.
Return a bytes object containing the provided values packed according
to the format string. See help(struct) for more on format strings.
[clinic start generated code]*/
static PyObject *
pack(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
pack_impl(PyObject *module, PyStructObject *s_object,
PyObject * const *values, Py_ssize_t values_length)
/*[clinic end generated code: output=2f874191ddecdec0 input=8144972342391de1]*/
{
PyObject *s_object = NULL;
PyObject *format, *result;
if (nargs == 0) {
PyErr_SetString(PyExc_TypeError, "missing format argument");
return NULL;
}
format = args[0];
if (!cache_struct_converter(module, format, (PyStructObject **)&s_object)) {
return NULL;
}
result = s_pack(s_object, args + 1, nargs - 1);
Py_DECREF(s_object);
return result;
return Struct_pack_impl(s_object, values, values_length);
}
PyDoc_STRVAR(pack_into_doc,
"pack_into(format, buffer, offset, v1, v2, ...)\n\
\n\
Pack the values v1, v2, ... according to the format string and write\n\
the packed bytes into the writable buffer buf starting at offset. Note\n\
that the offset is a required argument. See help(struct) for more\n\
on format strings.");
/*[clinic input]
pack_into
format as s_object: cache_struct
buffer: Py_buffer(accept={rwbuffer})
offset as offset_obj: object
/
*values: array
Pack values and write the packed bytes into the buffer.
Pack the provided values according to the format string and write the
packed bytes into the writable buffer starting at offset. Note that the
offset is a required argument. See help(struct) for more on format
strings.
[clinic start generated code]*/
static PyObject *
pack_into(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
pack_into_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer,
PyObject *offset_obj, PyObject * const *values,
Py_ssize_t values_length)
/*[clinic end generated code: output=148ef659a490eec3 input=3c5fe5bd3b6fd396]*/
{
PyObject *s_object = NULL;
PyObject *format, *result;
if (nargs == 0) {
PyErr_SetString(PyExc_TypeError, "missing format argument");
return NULL;
}
format = args[0];
if (!cache_struct_converter(module, format, (PyStructObject **)&s_object)) {
return NULL;
}
result = s_pack_into(s_object, args + 1, nargs - 1);
Py_DECREF(s_object);
return result;
return Struct_pack_into_impl(s_object, buffer, offset_obj,
values, values_length);
}
/*[clinic input]
@ -2606,14 +2577,13 @@ unpack
Return a tuple containing values unpacked according to the format string.
The buffer's size in bytes must be calcsize(format).
See help(struct) for more on format strings.
The buffer's size in bytes must be calcsize(format). See help(struct)
for more on format strings.
[clinic start generated code]*/
static PyObject *
unpack_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer)
/*[clinic end generated code: output=48ddd4d88eca8551 input=05fa3b91678da727]*/
/*[clinic end generated code: output=48ddd4d88eca8551 input=7df28c5d0b5b6f4e]*/
{
return Struct_unpack_impl(s_object, buffer);
}
@ -2628,15 +2598,14 @@ unpack_from
Return a tuple containing values unpacked according to the format string.
The buffer's size, minus offset, must be at least calcsize(format).
See help(struct) for more on format strings.
The buffer's size, minus offset, must be at least calcsize(format). See
help(struct) for more on format strings.
[clinic start generated code]*/
static PyObject *
unpack_from_impl(PyObject *module, PyStructObject *s_object,
Py_buffer *buffer, Py_ssize_t offset)
/*[clinic end generated code: output=1042631674c6e0d3 input=6e80a5398e985025]*/
/*[clinic end generated code: output=1042631674c6e0d3 input=599262b23559f6c5]*/
{
return Struct_unpack_from_impl(s_object, buffer, offset);
}
@ -2650,26 +2619,25 @@ iter_unpack
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.
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 calcsize(format).
[clinic start generated code]*/
static PyObject *
iter_unpack_impl(PyObject *module, PyStructObject *s_object,
PyObject *buffer)
/*[clinic end generated code: output=0ae50e250d20e74d input=b214a58869a3c98d]*/
/*[clinic end generated code: output=0ae50e250d20e74d input=ac5086c5c4ed68bb]*/
{
return Struct_iter_unpack((PyObject*)s_object, buffer);
return Struct_iter_unpack_impl(s_object, buffer);
}
static struct PyMethodDef module_functions[] = {
_CLEARCACHE_METHODDEF
CALCSIZE_METHODDEF
ITER_UNPACK_METHODDEF
{"pack", _PyCFunction_CAST(pack), METH_FASTCALL, pack_doc},
{"pack_into", _PyCFunction_CAST(pack_into), METH_FASTCALL, pack_into_doc},
PACK_METHODDEF
PACK_INTO_METHODDEF
UNPACK_METHODDEF
UNPACK_FROM_METHODDEF
{NULL, NULL} /* sentinel */

View File

@ -15,10 +15,8 @@ PyDoc_STRVAR(Struct___init____doc__,
"\n"
"Create a compiled struct object.\n"
"\n"
"Return a new Struct object which writes and reads binary data according to\n"
"the format string.\n"
"\n"
"See help(struct) for more on format strings.");
"Return a new Struct object which writes and reads binary data according\n"
"to the format string. See help(struct) for more on format strings.");
static int
Struct___init___impl(PyStructObject *self, PyObject *format);
@ -77,10 +75,9 @@ PyDoc_STRVAR(Struct_unpack__doc__,
"\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.");
"Unpack according to the struct format string. The buffer\'s\n"
"size in bytes must be the struct size. See help(struct) for more on\n"
"format strings.");
#define STRUCT_UNPACK_METHODDEF \
{"unpack", (PyCFunction)Struct_unpack, METH_O, Struct_unpack__doc__},
@ -114,12 +111,10 @@ PyDoc_STRVAR(Struct_unpack_from__doc__,
"\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, starting at position offset, must be\n"
"at least Struct.size.\n"
"\n"
"See help(struct) for more on format strings.");
"Values are unpacked according to the struct format string. The\n"
"buffer\'s size in bytes, starting at position offset, must be at\n"
"least the struct size. See help(struct) for more on format\n"
"strings.");
#define STRUCT_UNPACK_FROM_METHODDEF \
{"unpack_from", _PyCFunction_CAST(Struct_unpack_from), METH_FASTCALL|METH_KEYWORDS, Struct_unpack_from__doc__},
@ -206,9 +201,8 @@ PyDoc_STRVAR(Struct_iter_unpack__doc__,
"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.");
"invocation of unpack_from(). Requires that the bytes length be\n"
"a multiple of the struct size.");
#define STRUCT_ITER_UNPACK_METHODDEF \
{"iter_unpack", (PyCFunction)Struct_iter_unpack, METH_O, Struct_iter_unpack__doc__},
@ -226,6 +220,103 @@ Struct_iter_unpack(PyObject *self, PyObject *buffer)
return return_value;
}
PyDoc_STRVAR(Struct_pack__doc__,
"pack($self, /, *values)\n"
"--\n"
"\n"
"Pack values and return the packed bytes.\n"
"\n"
"Return a bytes object containing the provided values packed\n"
"according to the struct format string. See help(struct) for more on\n"
"format strings.");
#define STRUCT_PACK_METHODDEF \
{"pack", _PyCFunction_CAST(Struct_pack), METH_FASTCALL, Struct_pack__doc__},
static PyObject *
Struct_pack_impl(PyStructObject *self, PyObject * const *values,
Py_ssize_t values_length);
static PyObject *
Struct_pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
{
PyObject *return_value = NULL;
PyObject * const *values;
Py_ssize_t values_length;
values = args;
values_length = nargs;
return_value = Struct_pack_impl((PyStructObject *)self, values, values_length);
return return_value;
}
PyDoc_STRVAR(Struct_pack_into__doc__,
"pack_into($self, buffer, offset, /, *values)\n"
"--\n"
"\n"
"Pack values and write the packed bytes into the buffer.\n"
"\n"
"Pack the provided values according to the struct format string\n"
"and write the packed bytes into the writable buffer starting at\n"
"offset. Note that the offset is a required argument. See\n"
"help(struct) for more on format strings.");
#define STRUCT_PACK_INTO_METHODDEF \
{"pack_into", _PyCFunction_CAST(Struct_pack_into), METH_FASTCALL, Struct_pack_into__doc__},
static PyObject *
Struct_pack_into_impl(PyStructObject *self, Py_buffer *buffer,
PyObject *offset_obj, PyObject * const *values,
Py_ssize_t values_length);
static PyObject *
Struct_pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
{
PyObject *return_value = NULL;
Py_buffer buffer = {NULL, NULL};
PyObject *offset_obj;
PyObject * const *values;
Py_ssize_t values_length;
if (!_PyArg_CheckPositional("pack_into", nargs, 2, PY_SSIZE_T_MAX)) {
goto exit;
}
if (PyObject_GetBuffer(args[0], &buffer, PyBUF_WRITABLE) < 0) {
_PyArg_BadArgument("pack_into", "argument 1", "read-write bytes-like object", args[0]);
goto exit;
}
offset_obj = args[1];
values = args + 2;
values_length = nargs - 2;
return_value = Struct_pack_into_impl((PyStructObject *)self, &buffer, offset_obj, values, values_length);
exit:
/* Cleanup for buffer */
if (buffer.obj) {
PyBuffer_Release(&buffer);
}
return return_value;
}
PyDoc_STRVAR(Struct___sizeof____doc__,
"__sizeof__($self, /)\n"
"--\n"
"\n");
#define STRUCT___SIZEOF___METHODDEF \
{"__sizeof__", (PyCFunction)Struct___sizeof__, METH_NOARGS, Struct___sizeof____doc__},
static PyObject *
Struct___sizeof___impl(PyStructObject *self);
static PyObject *
Struct___sizeof__(PyObject *self, PyObject *Py_UNUSED(ignored))
{
return Struct___sizeof___impl((PyStructObject *)self);
}
PyDoc_STRVAR(_clearcache__doc__,
"_clearcache($module, /)\n"
"--\n"
@ -279,15 +370,110 @@ exit:
return return_value;
}
PyDoc_STRVAR(pack__doc__,
"pack($module, format, /, *values)\n"
"--\n"
"\n"
"Pack values and return the packed bytes.\n"
"\n"
"Return a bytes object containing the provided values packed according\n"
"to the format string. See help(struct) for more on format strings.");
#define PACK_METHODDEF \
{"pack", _PyCFunction_CAST(pack), METH_FASTCALL, pack__doc__},
static PyObject *
pack_impl(PyObject *module, PyStructObject *s_object,
PyObject * const *values, Py_ssize_t values_length);
static PyObject *
pack(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
{
PyObject *return_value = NULL;
PyStructObject *s_object = NULL;
PyObject * const *values;
Py_ssize_t values_length;
if (!_PyArg_CheckPositional("pack", nargs, 1, PY_SSIZE_T_MAX)) {
goto exit;
}
if (!cache_struct_converter(module, args[0], &s_object)) {
goto exit;
}
values = args + 1;
values_length = nargs - 1;
return_value = pack_impl(module, s_object, values, values_length);
exit:
/* Cleanup for s_object */
Py_XDECREF(s_object);
return return_value;
}
PyDoc_STRVAR(pack_into__doc__,
"pack_into($module, format, buffer, offset, /, *values)\n"
"--\n"
"\n"
"Pack values and write the packed bytes into the buffer.\n"
"\n"
"Pack the provided values according to the format string and write the\n"
"packed bytes into the writable buffer starting at offset. Note that the\n"
"offset is a required argument. See help(struct) for more on format\n"
"strings.");
#define PACK_INTO_METHODDEF \
{"pack_into", _PyCFunction_CAST(pack_into), METH_FASTCALL, pack_into__doc__},
static PyObject *
pack_into_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer,
PyObject *offset_obj, PyObject * const *values,
Py_ssize_t values_length);
static PyObject *
pack_into(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
{
PyObject *return_value = NULL;
PyStructObject *s_object = NULL;
Py_buffer buffer = {NULL, NULL};
PyObject *offset_obj;
PyObject * const *values;
Py_ssize_t values_length;
if (!_PyArg_CheckPositional("pack_into", nargs, 3, PY_SSIZE_T_MAX)) {
goto exit;
}
if (!cache_struct_converter(module, args[0], &s_object)) {
goto exit;
}
if (PyObject_GetBuffer(args[1], &buffer, PyBUF_WRITABLE) < 0) {
_PyArg_BadArgument("pack_into", "argument 2", "read-write bytes-like object", args[1]);
goto exit;
}
offset_obj = args[2];
values = args + 3;
values_length = nargs - 3;
return_value = pack_into_impl(module, s_object, &buffer, offset_obj, values, values_length);
exit:
/* Cleanup for s_object */
Py_XDECREF(s_object);
/* Cleanup for buffer */
if (buffer.obj) {
PyBuffer_Release(&buffer);
}
return return_value;
}
PyDoc_STRVAR(unpack__doc__,
"unpack($module, format, buffer, /)\n"
"--\n"
"\n"
"Return a tuple containing values unpacked according to the format string.\n"
"\n"
"The buffer\'s size in bytes must be calcsize(format).\n"
"\n"
"See help(struct) for more on format strings.");
"The buffer\'s size in bytes must be calcsize(format). See help(struct)\n"
"for more on format strings.");
#define UNPACK_METHODDEF \
{"unpack", _PyCFunction_CAST(unpack), METH_FASTCALL, unpack__doc__},
@ -330,9 +516,8 @@ PyDoc_STRVAR(unpack_from__doc__,
"\n"
"Return a tuple containing values unpacked according to the format string.\n"
"\n"
"The buffer\'s size, minus offset, must be at least calcsize(format).\n"
"\n"
"See help(struct) for more on format strings.");
"The buffer\'s size, minus offset, must be at least calcsize(format). See\n"
"help(struct) for more on format strings.");
#define UNPACK_FROM_METHODDEF \
{"unpack_from", _PyCFunction_CAST(unpack_from), METH_FASTCALL|METH_KEYWORDS, unpack_from__doc__},
@ -424,10 +609,9 @@ PyDoc_STRVAR(iter_unpack__doc__,
"\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.");
"The bytes are unpacked according to the format string, like a repeated\n"
"invocation of unpack_from(). Requires that the bytes length be\n"
"a multiple of calcsize(format).");
#define ITER_UNPACK_METHODDEF \
{"iter_unpack", _PyCFunction_CAST(iter_unpack), METH_FASTCALL, iter_unpack__doc__},
@ -458,4 +642,4 @@ exit:
return return_value;
}
/*[clinic end generated code: output=caa7f36443e91cb9 input=a9049054013a1b77]*/
/*[clinic end generated code: output=dc4f86c77ab3b1c9 input=a9049054013a1b77]*/