pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/python/cpython/commit/a5a55902c19ef7583a0185a7dd90dcfa138ca8a5

Issue #29300: Use Argument Clinic for getting struct object from the … · python/cpython@a5a5590 · GitHub
Skip to content

Commit a5a5590

Browse files
Issue #29300: Use Argument Clinic for getting struct object from the format.
1 parent 8973de5 commit a5a5590

2 files changed

Lines changed: 103 additions & 83 deletions

File tree

Modules/_struct.c

Lines changed: 52 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,19 @@ typedef struct { char c; long long x; } s_long_long;
8585
#pragma options align=reset
8686
#endif
8787

88+
/*[python input]
89+
class cache_struct_converter(CConverter):
90+
type = 'PyStructObject *'
91+
converter = 'cache_struct_converter'
92+
c_default = "NULL"
93+
94+
def cleanup(self):
95+
return "Py_XDECREF(%s);\n" % self.name
96+
[python start generated code]*/
97+
/*[python end generated code: output=da39a3ee5e6b4b0d input=49957cca130ffb63]*/
98+
99+
static int cache_struct_converter(PyObject *, PyObject **);
100+
88101
#include "clinic/_struct.c.h"
89102

90103
/* Helper for integer format codes: converts an arbitrary Python object to a
@@ -2037,21 +2050,27 @@ PyTypeObject PyStructType = {
20372050
#define MAXCACHE 100
20382051
static PyObject *cache = NULL;
20392052

2040-
static PyStructObject *
2041-
cache_struct(PyObject *fmt)
2053+
static int
2054+
cache_struct_converter(PyObject *fmt, PyObject **ptr)
20422055
{
20432056
PyObject * s_object;
20442057

2058+
if (fmt == NULL) {
2059+
Py_DECREF(*ptr);
2060+
return 1;
2061+
}
2062+
20452063
if (cache == NULL) {
20462064
cache = PyDict_New();
20472065
if (cache == NULL)
2048-
return NULL;
2066+
return 0;
20492067
}
20502068

20512069
s_object = PyDict_GetItem(cache, fmt);
20522070
if (s_object != NULL) {
20532071
Py_INCREF(s_object);
2054-
return (PyStructObject *)s_object;
2072+
*ptr = s_object;
2073+
return Py_CLEANUP_SUPPORTED;
20552074
}
20562075

20572076
s_object = PyObject_CallFunctionObjArgs((PyObject *)(&PyStructType), fmt, NULL);
@@ -2061,8 +2080,10 @@ cache_struct(PyObject *fmt)
20612080
/* Attempt to cache the result */
20622081
if (PyDict_SetItem(cache, fmt, s_object) == -1)
20632082
PyErr_Clear();
2083+
*ptr = s_object;
2084+
return Py_CLEANUP_SUPPORTED;
20642085
}
2065-
return (PyStructObject *)s_object;
2086+
return 0;
20662087
}
20672088

20682089
/*[clinic input]
@@ -2081,25 +2102,19 @@ _clearcache_impl(PyObject *module)
20812102

20822103

20832104
/*[clinic input]
2084-
calcsize
2105+
calcsize -> Py_ssize_t
20852106
2086-
format: object
2107+
format as s_object: cache_struct
20872108
/
20882109
20892110
Return size in bytes of the struct described by the format string.
20902111
[clinic start generated code]*/
20912112

2092-
static PyObject *
2093-
calcsize(PyObject *module, PyObject *format)
2094-
/*[clinic end generated code: output=90fbcf191fe9470a input=55488303a06777fa]*/
2113+
static Py_ssize_t
2114+
calcsize_impl(PyObject *module, PyStructObject *s_object)
2115+
/*[clinic end generated code: output=db7d23d09c6932c4 input=96a6a590c7717ecd]*/
20952116
{
2096-
Py_ssize_t n;
2097-
PyStructObject *s_object = cache_struct(format);
2098-
if (s_object == NULL)
2099-
return NULL;
2100-
n = s_object->s_size;
2101-
Py_DECREF(s_object);
2102-
return PyLong_FromSsize_t(n);
2117+
return s_object->s_size;
21032118
}
21042119

21052120
PyDoc_STRVAR(pack_doc,
@@ -2111,7 +2126,7 @@ to the format string. See help(struct) for more on format strings.");
21112126
static PyObject *
21122127
pack(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
21132128
{
2114-
PyStructObject *s_object;
2129+
PyObject *s_object = NULL;
21152130
PyObject *format, *result;
21162131

21172132
if (nargs == 0) {
@@ -2120,11 +2135,10 @@ pack(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
21202135
}
21212136
format = args[0];
21222137

2123-
s_object = cache_struct(format);
2124-
if (s_object == NULL) {
2138+
if (!cache_struct_converter(format, &s_object)) {
21252139
return NULL;
21262140
}
2127-
result = s_pack((PyObject *)s_object, args + 1, nargs - 1, kwnames);
2141+
result = s_pack(s_object, args + 1, nargs - 1, kwnames);
21282142
Py_DECREF(s_object);
21292143
return result;
21302144
}
@@ -2140,7 +2154,7 @@ on format strings.");
21402154
static PyObject *
21412155
pack_into(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
21422156
{
2143-
PyStructObject *s_object;
2157+
PyObject *s_object = NULL;
21442158
PyObject *format, *result;
21452159

21462160
if (nargs == 0) {
@@ -2149,19 +2163,18 @@ pack_into(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
21492163
}
21502164
format = args[0];
21512165

2152-
s_object = cache_struct(format);
2153-
if (s_object == NULL) {
2166+
if (!cache_struct_converter(format, &s_object)) {
21542167
return NULL;
21552168
}
2156-
result = s_pack_into((PyObject *)s_object, args + 1, nargs - 1, kwnames);
2169+
result = s_pack_into(s_object, args + 1, nargs - 1, kwnames);
21572170
Py_DECREF(s_object);
21582171
return result;
21592172
}
21602173

21612174
/*[clinic input]
21622175
unpack
21632176
2164-
format: object
2177+
format as s_object: cache_struct
21652178
buffer: Py_buffer
21662179
/
21672180
@@ -2173,24 +2186,16 @@ See help(struct) for more on format strings.
21732186
[clinic start generated code]*/
21742187

21752188
static PyObject *
2176-
unpack_impl(PyObject *module, PyObject *format, Py_buffer *buffer)
2177-
/*[clinic end generated code: output=f75ada02aaa33b3b input=654078e6660c2df0]*/
2189+
unpack_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer)
2190+
/*[clinic end generated code: output=48ddd4d88eca8551 input=05fa3b91678da727]*/
21782191
{
2179-
PyStructObject *s_object;
2180-
PyObject *result;
2181-
2182-
s_object = cache_struct(format);
2183-
if (s_object == NULL)
2184-
return NULL;
2185-
result = Struct_unpack_impl(s_object, buffer);
2186-
Py_DECREF(s_object);
2187-
return result;
2192+
return Struct_unpack_impl(s_object, buffer);
21882193
}
21892194

21902195
/*[clinic input]
21912196
unpack_from
21922197
2193-
format: object
2198+
format as s_object: cache_struct
21942199
/
21952200
buffer: Py_buffer
21962201
offset: Py_ssize_t = 0
@@ -2203,27 +2208,17 @@ See help(struct) for more on format strings.
22032208
[clinic start generated code]*/
22042209

22052210
static PyObject *
2206-
unpack_from_impl(PyObject *module, PyObject *format, Py_buffer *buffer,
2207-
Py_ssize_t offset)
2208-
/*[clinic end generated code: output=2492f0c3a0b82577 input=9ead76c6ac7164f7]*/
2211+
unpack_from_impl(PyObject *module, PyStructObject *s_object,
2212+
Py_buffer *buffer, Py_ssize_t offset)
2213+
/*[clinic end generated code: output=1042631674c6e0d3 input=6e80a5398e985025]*/
22092214
{
2210-
PyStructObject *s_object;
2211-
PyObject *result;
2212-
2213-
s_object = cache_struct(format);
2214-
if (s_object == NULL) {
2215-
return NULL;
2216-
}
2217-
result = Struct_unpack_from_impl(s_object, buffer, offset);
2218-
2219-
Py_DECREF(s_object);
2220-
return result;
2215+
return Struct_unpack_from_impl(s_object, buffer, offset);
22212216
}
22222217

22232218
/*[clinic input]
22242219
iter_unpack
22252220
2226-
format: object
2221+
format as s_object: cache_struct
22272222
buffer: object
22282223
/
22292224
@@ -2236,19 +2231,11 @@ Requires that the bytes length be a multiple of the format struct size.
22362231
[clinic start generated code]*/
22372232

22382233
static PyObject *
2239-
iter_unpack_impl(PyObject *module, PyObject *format, PyObject *buffer)
2240-
/*[clinic end generated code: output=b1291e97a6d4cf3c input=8674dfd2f0dae416]*/
2234+
iter_unpack_impl(PyObject *module, PyStructObject *s_object,
2235+
PyObject *buffer)
2236+
/*[clinic end generated code: output=0ae50e250d20e74d input=b214a58869a3c98d]*/
22412237
{
2242-
PyStructObject *s_object;
2243-
PyObject *result;
2244-
2245-
s_object = cache_struct(format);
2246-
if (s_object == NULL)
2247-
return NULL;
2248-
2249-
result = Struct_iter_unpack(s_object, buffer);
2250-
Py_DECREF(s_object);
2251-
return result;
2238+
return Struct_iter_unpack(s_object, buffer);
22522239
}
22532240

22542241
static struct PyMethodDef module_functions[] = {

Modules/clinic/_struct.c.h

Lines changed: 51 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,32 @@ PyDoc_STRVAR(calcsize__doc__,
155155
#define CALCSIZE_METHODDEF \
156156
{"calcsize", (PyCFunction)calcsize, METH_O, calcsize__doc__},
157157

158+
static Py_ssize_t
159+
calcsize_impl(PyObject *module, PyStructObject *s_object);
160+
161+
static PyObject *
162+
calcsize(PyObject *module, PyObject *arg)
163+
{
164+
PyObject *return_value = NULL;
165+
PyStructObject *s_object = NULL;
166+
Py_ssize_t _return_value;
167+
168+
if (!PyArg_Parse(arg, "O&:calcsize", cache_struct_converter, &s_object)) {
169+
goto exit;
170+
}
171+
_return_value = calcsize_impl(module, s_object);
172+
if ((_return_value == -1) && PyErr_Occurred()) {
173+
goto exit;
174+
}
175+
return_value = PyLong_FromSsize_t(_return_value);
176+
177+
exit:
178+
/* Cleanup for s_object */
179+
Py_XDECREF(s_object);
180+
181+
return return_value;
182+
}
183+
158184
PyDoc_STRVAR(unpack__doc__,
159185
"unpack($module, format, buffer, /)\n"
160186
"--\n"
@@ -169,26 +195,28 @@ PyDoc_STRVAR(unpack__doc__,
169195
{"unpack", (PyCFunction)unpack, METH_FASTCALL, unpack__doc__},
170196

171197
static PyObject *
172-
unpack_impl(PyObject *module, PyObject *format, Py_buffer *buffer);
198+
unpack_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer);
173199

174200
static PyObject *
175201
unpack(PyObject *module, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
176202
{
177203
PyObject *return_value = NULL;
178-
PyObject *format;
204+
PyStructObject *s_object = NULL;
179205
Py_buffer buffer = {NULL, NULL};
180206

181-
if (!_PyArg_ParseStack(args, nargs, "Oy*:unpack",
182-
&format, &buffer)) {
207+
if (!_PyArg_ParseStack(args, nargs, "O&y*:unpack",
208+
cache_struct_converter, &s_object, &buffer)) {
183209
goto exit;
184210
}
185211

186212
if (!_PyArg_NoStackKeywords("unpack", kwnames)) {
187213
goto exit;
188214
}
189-
return_value = unpack_impl(module, format, &buffer);
215+
return_value = unpack_impl(module, s_object, &buffer);
190216

191217
exit:
218+
/* Cleanup for s_object */
219+
Py_XDECREF(s_object);
192220
/* Cleanup for buffer */
193221
if (buffer.obj) {
194222
PyBuffer_Release(&buffer);
@@ -211,26 +239,28 @@ PyDoc_STRVAR(unpack_from__doc__,
211239
{"unpack_from", (PyCFunction)unpack_from, METH_FASTCALL, unpack_from__doc__},
212240

213241
static PyObject *
214-
unpack_from_impl(PyObject *module, PyObject *format, Py_buffer *buffer,
215-
Py_ssize_t offset);
242+
unpack_from_impl(PyObject *module, PyStructObject *s_object,
243+
Py_buffer *buffer, Py_ssize_t offset);
216244

217245
static PyObject *
218246
unpack_from(PyObject *module, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
219247
{
220248
PyObject *return_value = NULL;
221249
static const char * const _keywords[] = {"", "buffer", "offset", NULL};
222-
static _PyArg_Parser _parser = {"Oy*|n:unpack_from", _keywords, 0};
223-
PyObject *format;
250+
static _PyArg_Parser _parser = {"O&y*|n:unpack_from", _keywords, 0};
251+
PyStructObject *s_object = NULL;
224252
Py_buffer buffer = {NULL, NULL};
225253
Py_ssize_t offset = 0;
226254

227255
if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
228-
&format, &buffer, &offset)) {
256+
cache_struct_converter, &s_object, &buffer, &offset)) {
229257
goto exit;
230258
}
231-
return_value = unpack_from_impl(module, format, &buffer, offset);
259+
return_value = unpack_from_impl(module, s_object, &buffer, offset);
232260

233261
exit:
262+
/* Cleanup for s_object */
263+
Py_XDECREF(s_object);
234264
/* Cleanup for buffer */
235265
if (buffer.obj) {
236266
PyBuffer_Release(&buffer);
@@ -254,27 +284,30 @@ PyDoc_STRVAR(iter_unpack__doc__,
254284
{"iter_unpack", (PyCFunction)iter_unpack, METH_FASTCALL, iter_unpack__doc__},
255285

256286
static PyObject *
257-
iter_unpack_impl(PyObject *module, PyObject *format, PyObject *buffer);
287+
iter_unpack_impl(PyObject *module, PyStructObject *s_object,
288+
PyObject *buffer);
258289

259290
static PyObject *
260291
iter_unpack(PyObject *module, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
261292
{
262293
PyObject *return_value = NULL;
263-
PyObject *format;
294+
PyStructObject *s_object = NULL;
264295
PyObject *buffer;
265296

266-
if (!_PyArg_UnpackStack(args, nargs, "iter_unpack",
267-
2, 2,
268-
&format, &buffer)) {
297+
if (!_PyArg_ParseStack(args, nargs, "O&O:iter_unpack",
298+
cache_struct_converter, &s_object, &buffer)) {
269299
goto exit;
270300
}
271301

272302
if (!_PyArg_NoStackKeywords("iter_unpack", kwnames)) {
273303
goto exit;
274304
}
275-
return_value = iter_unpack_impl(module, format, buffer);
305+
return_value = iter_unpack_impl(module, s_object, buffer);
276306

277307
exit:
308+
/* Cleanup for s_object */
309+
Py_XDECREF(s_object);
310+
278311
return return_value;
279312
}
280-
/*[clinic end generated code: output=0714090a5d0ea8ce input=a9049054013a1b77]*/
313+
/*[clinic end generated code: output=03e0d193ab1983f9 input=a9049054013a1b77]*/

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy