X Tutup
Skip to content

Commit fe54dd8

Browse files
committed
Add _PyArg_UnpackStack() function helper
Issue python#29286.
1 parent 259f0e4 commit fe54dd8

File tree

2 files changed

+65
-18
lines changed

2 files changed

+65
-18
lines changed

Include/modsupport.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,16 @@ PyAPI_FUNC(int) PyArg_UnpackTuple(PyObject *, const char *, Py_ssize_t, Py_ssize
4747
PyAPI_FUNC(PyObject *) Py_BuildValue(const char *, ...);
4848
PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...);
4949
#endif
50+
5051
#ifndef Py_LIMITED_API
52+
PyAPI_FUNC(int) _PyArg_UnpackStack(
53+
PyObject **args,
54+
Py_ssize_t nargs,
55+
const char *name,
56+
Py_ssize_t min,
57+
Py_ssize_t max,
58+
...);
59+
5160
PyAPI_FUNC(int) _PyArg_NoKeywords(const char *funcname, PyObject *kwargs);
5261
PyAPI_FUNC(int) _PyArg_NoStackKeywords(const char *funcname, PyObject *kwnames);
5362
PyAPI_FUNC(int) _PyArg_NoPositional(const char *funcname, PyObject *args);
@@ -56,6 +65,7 @@ PyAPI_FUNC(int) PyArg_VaParse(PyObject *, const char *, va_list);
5665
PyAPI_FUNC(int) PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *,
5766
const char *, char **, va_list);
5867
#endif
68+
5969
PyAPI_FUNC(PyObject *) Py_VaBuildValue(const char *, va_list);
6070
#ifndef Py_LIMITED_API
6171
PyAPI_FUNC(PyObject **) _Py_VaBuildStack(

Python/getargs.c

Lines changed: 55 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2363,21 +2363,16 @@ skipitem(const char **p_format, va_list *p_va, int flags)
23632363
}
23642364

23652365

2366-
int
2367-
PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...)
2366+
static int
2367+
PyArg_UnpackStack_impl(PyObject **args, Py_ssize_t l, const char *name,
2368+
Py_ssize_t min, Py_ssize_t max, va_list vargs)
23682369
{
2369-
Py_ssize_t i, l;
2370+
Py_ssize_t i;
23702371
PyObject **o;
2371-
va_list vargs;
23722372

23732373
assert(min >= 0);
23742374
assert(min <= max);
2375-
if (!PyTuple_Check(args)) {
2376-
PyErr_SetString(PyExc_SystemError,
2377-
"PyArg_UnpackTuple() argument list is not a tuple");
2378-
return 0;
2379-
}
2380-
l = PyTuple_GET_SIZE(args);
2375+
23812376
if (l < min) {
23822377
if (name != NULL)
23832378
PyErr_Format(
@@ -2392,8 +2387,11 @@ PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t m
23922387
(min == max ? "" : "at least "), min, l);
23932388
return 0;
23942389
}
2395-
if (l == 0)
2390+
2391+
if (l == 0) {
23962392
return 1;
2393+
}
2394+
23972395
if (l > max) {
23982396
if (name != NULL)
23992397
PyErr_Format(
@@ -2409,17 +2407,54 @@ PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t m
24092407
return 0;
24102408
}
24112409

2410+
for (i = 0; i < l; i++) {
2411+
o = va_arg(vargs, PyObject **);
2412+
*o = args[i];
2413+
}
2414+
return 1;
2415+
}
2416+
2417+
int
2418+
PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...)
2419+
{
2420+
PyObject **stack;
2421+
Py_ssize_t nargs;
2422+
int retval;
2423+
va_list vargs;
2424+
2425+
if (!PyTuple_Check(args)) {
2426+
PyErr_SetString(PyExc_SystemError,
2427+
"PyArg_UnpackTuple() argument list is not a tuple");
2428+
return 0;
2429+
}
2430+
stack = &PyTuple_GET_ITEM(args, 0);
2431+
nargs = PyTuple_GET_SIZE(args);
2432+
24122433
#ifdef HAVE_STDARG_PROTOTYPES
24132434
va_start(vargs, max);
24142435
#else
24152436
va_start(vargs);
24162437
#endif
2417-
for (i = 0; i < l; i++) {
2418-
o = va_arg(vargs, PyObject **);
2419-
*o = PyTuple_GET_ITEM(args, i);
2420-
}
2438+
retval = PyArg_UnpackStack_impl(stack, nargs, name, min, max, vargs);
24212439
va_end(vargs);
2422-
return 1;
2440+
return retval;
2441+
}
2442+
2443+
int
2444+
_PyArg_UnpackStack(PyObject **args, Py_ssize_t nargs, const char *name,
2445+
Py_ssize_t min, Py_ssize_t max, ...)
2446+
{
2447+
int retval;
2448+
va_list vargs;
2449+
2450+
#ifdef HAVE_STDARG_PROTOTYPES
2451+
va_start(vargs, max);
2452+
#else
2453+
va_start(vargs);
2454+
#endif
2455+
retval = PyArg_UnpackStack_impl(args, nargs, name, min, max, vargs);
2456+
va_end(vargs);
2457+
return retval;
24232458
}
24242459

24252460

@@ -2431,8 +2466,9 @@ PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t m
24312466
int
24322467
_PyArg_NoKeywords(const char *funcname, PyObject *kwargs)
24332468
{
2434-
if (kwargs == NULL)
2469+
if (kwargs == NULL) {
24352470
return 1;
2471+
}
24362472
if (!PyDict_CheckExact(kwargs)) {
24372473
PyErr_BadInternalCall();
24382474
return 0;
@@ -2450,8 +2486,9 @@ _PyArg_NoKeywords(const char *funcname, PyObject *kwargs)
24502486
int
24512487
_PyArg_NoStackKeywords(const char *funcname, PyObject *kwnames)
24522488
{
2453-
if (kwnames == NULL)
2489+
if (kwnames == NULL) {
24542490
return 1;
2491+
}
24552492
assert(PyTuple_CheckExact(kwnames));
24562493
if (PyTuple_GET_SIZE(kwnames) == 0) {
24572494
return 1;

0 commit comments

Comments
 (0)
X Tutup