Skip to content

Commit e4616e6

Browse files
committed
PyArg_UnpackTuple(): New argument unpacking function suggested by Jim
Fulton, based on code Jim supplied.
1 parent 4855b02 commit e4616e6

2 files changed

Lines changed: 61 additions & 0 deletions

File tree

Include/modsupport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ extern DL_IMPORT(int) PyArg_Parse(PyObject *, char *, ...);
1313
extern DL_IMPORT(int) PyArg_ParseTuple(PyObject *, char *, ...);
1414
extern DL_IMPORT(int) PyArg_ParseTupleAndKeywords(PyObject *, PyObject *,
1515
char *, char **, ...);
16+
extern DL_IMPORT(int) PyArg_UnpackTuple(PyObject *, char *, int, int, ...);
1617
extern DL_IMPORT(PyObject *) Py_BuildValue(char *, ...);
1718

1819
extern DL_IMPORT(int) PyArg_VaParse(PyObject *, char *, va_list);

Python/getargs.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1360,3 +1360,63 @@ skipitem(char **p_format, va_list *p_va)
13601360
*p_format = format;
13611361
return NULL;
13621362
}
1363+
1364+
1365+
int
1366+
PyArg_UnpackTuple(PyObject *args, char *name, int min, int max, ...)
1367+
{
1368+
int i, l;
1369+
PyObject **o;
1370+
va_list vargs;
1371+
1372+
#ifdef HAVE_STDARG_PROTOTYPES
1373+
va_start(vargs, max);
1374+
#else
1375+
va_start(vargs);
1376+
#endif
1377+
1378+
assert(min >= 0);
1379+
assert(min <= max);
1380+
if (!PyTuple_Check(args)) {
1381+
PyErr_SetString(PyExc_SystemError,
1382+
"PyArg_UnpackTuple() argument list is not a tuple");
1383+
return 0;
1384+
}
1385+
l = PyTuple_GET_SIZE(args);
1386+
if (l < min) {
1387+
if (name != NULL)
1388+
PyErr_Format(
1389+
PyExc_TypeError,
1390+
"%s expected %s%d arguments, got %d",
1391+
name, (min == max ? "" : "at least "), min, l);
1392+
else
1393+
PyErr_Format(
1394+
PyExc_TypeError,
1395+
"unpacked tuple should have %s%d elements,"
1396+
" but has %d",
1397+
(min == max ? "" : "at least "), min, l);
1398+
va_end(vargs);
1399+
return 0;
1400+
}
1401+
if (l > max) {
1402+
if (name != NULL)
1403+
PyErr_Format(
1404+
PyExc_TypeError,
1405+
"%s expected %s%d arguments, got %d",
1406+
name, (min == max ? "" : "at most "), max, l);
1407+
else
1408+
PyErr_Format(
1409+
PyExc_TypeError,
1410+
"unpacked tuple should have %s%d elements,"
1411+
" but has %d",
1412+
(min == max ? "" : "at most "), max, l);
1413+
va_end(vargs);
1414+
return 0;
1415+
}
1416+
for (i = 0; i < l; i++) {
1417+
o = va_arg(vargs, PyObject **);
1418+
*o = PyTuple_GET_ITEM(args, i);
1419+
}
1420+
va_end(vargs);
1421+
return 1;
1422+
}

0 commit comments

Comments
 (0)