Index: Python/getargs.c =================================================================== --- Python/getargs.c (revision 87989) +++ Python/getargs.c (working copy) @@ -1,4 +1,3 @@ - /* New getargs implementation */ #include "Python.h" @@ -475,6 +474,47 @@ n++; } + if (PyTuple_Check(arg)) { + if ((i = PyTuple_GET_SIZE(arg)) != n) { + levels[0] = 0; + PyOS_snprintf(msgbuf, bufsize, + toplevel ? "expected %d arguments, not %d" : + "must be sequence of length %d, not %d", + n, i); + return msgbuf; + } + + format = *p_format; + for (i = 0; i < n; i++) { + char *msg; + msg = convertitem(PyTuple_GET_ITEM(arg, i), &format, + p_va, flags, levels+1, + msgbuf, bufsize, freelist); + if (msg != NULL) { + levels[0] = i+1; + return msg; + } + } + *p_format = format; + return NULL; + } + + if (!toplevel) { + /* Refuse to unpack non-tuple if the format calls for borrowed + * references. */ + format = *p_format; + for (i = 0; i < n; i++) + if ((format[i] == 'O' && format[i+1] != '&') || + strchr("USY", format[i])) { + levels[0] = 0; + PyOS_snprintf(msgbuf, bufsize, + "must be %d-tuple, not %.50s", + n, + arg == Py_None ? "None" : arg->ob_type->tp_name); + return msgbuf; + } + } + if (!PySequence_Check(arg) || PyBytes_Check(arg)) { levels[0] = 0; PyOS_snprintf(msgbuf, bufsize,