PyObject *item; if (*format == '|') format++; item = PyDict_GetItemString(keywords, kwlist[i]); if (item != NULL) { Py_INCREF(item); msg = convertitem(item, &format, p_va, flags, levels, msgbuf, sizeof(msgbuf), &freelist); Py_DECREF(item); if (msg) { seterror(i+1, msg, levels, fname, message); return cleanreturn(0, freelist); } --nkeywords; if (nkeywords == 0) break; } else if (PyErr_Occurred()) return cleanreturn(0, freelist); else { msg = skipitem(&format, p_va, flags); if (msg) { levels[0] = 0; seterror(i+1, msg, levels, fname, message); return cleanreturn(0, freelist); } } } /* make sure there are no extraneous keyword arguments */ if (nkeywords > 0) { PyObject *key, *value; Py_ssize_t pos = 0; while (PyDict_Next(keywords, &pos, &key, &value)) { int match = 0; char *ks; if (!PyString_Check(key)) { PyErr_SetString(PyExc_TypeError, "keywords must be strings"); return cleanreturn(0, freelist); } ks = PyString_AsString(key); for (i = 0; i < max; i++) { if (!strcmp(ks, kwlist[i])) { match = 1; break; } } if (!match) { PyErr_Format(PyExc_TypeError, "'%s' is an invalid keyword " "argument for this function", ks); return cleanreturn(0, freelist); } } } return cleanreturn(1, freelist);} static char *skipitem(const char **p_format, va_list *p_va, int flags){ const char *format = *p_format; char c = *format++; switch (c) { /* simple codes * The individual types (second arg of va_arg) are irrelevant */ case 'b': /* byte -- very short int */ case 'B': /* byte as bitfield */ case 'h': /* short int */ case 'H': /* short int as bitfield */ case 'i': /* int */ case 'I': /* int sized bitfield */ case 'l': /* long int */ case 'k': /* long int sized bitfield */#ifdef HAVE_LONG_LONG case 'L': /* PY_LONG_LONG */ case 'K': /* PY_LONG_LONG sized bitfield */#endif case 'f': /* float */ case 'd': /* double */#ifndef WITHOUT_COMPLEX case 'D': /* complex double */#endif case 'c': /* char */ { (void) va_arg(*p_va, void *); break; } case 'n': /* Py_ssize_t */ { (void) va_arg(*p_va, Py_ssize_t *); break; } /* string codes */ case 'e': /* string with encoding */ { (void) va_arg(*p_va, const char *); if (!(*format == 's' || *format == 't')) /* after 'e', only 's' and 't' is allowed */ goto err; format++; /* explicit fallthrough to string cases */ } case 's': /* string */ case 'z': /* string or None */#ifdef Py_USING_UNICODE case 'u': /* unicode string */#endif case 't': /* buffer, read-only */ case 'w': /* buffer, read-write */ { (void) va_arg(*p_va, char **); if (*format == '#') { if (flags & FLAG_SIZE_T) (void) va_arg(*p_va, Py_ssize_t *); else (void) va_arg(*p_va, int *); format++; } break; } /* object codes */ case 'S': /* string object */#ifdef Py_USING_UNICODE case 'U': /* unicode string object */#endif { (void) va_arg(*p_va, PyObject **); break; } case 'O': /* object */ { if (*format == '!') { format++; (void) va_arg(*p_va, PyTypeObject*); (void) va_arg(*p_va, PyObject **); }#if 0/* I don't know what this is for */ else if (*format == '?') { inquiry pred = va_arg(*p_va, inquiry); format++; if ((*pred)(arg)) { (void) va_arg(*p_va, PyObject **); } }#endif else if (*format == '&') { typedef int (*converter)(PyObject *, void *); (void) va_arg(*p_va, converter); (void) va_arg(*p_va, void *); format++; } else { (void) va_arg(*p_va, PyObject **); } break; } default:err: return "impossible<bad format char>"; } /* The "(...)" format code for tuples is not handled here because * it is not allowed with keyword args. */ *p_format = format; return NULL;} intPyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...){ Py_ssize_t i, l; PyObject **o; va_list vargs; #ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, max);#else va_start(vargs);#endif assert(min >= 0); assert(min <= max); if (!PyTuple_Check(args)) { PyErr_SetString(PyExc_SystemError, "PyArg_UnpackTuple() argument list is not a tuple"); return 0; } l = PyTuple_GET_SIZE(args); if (l < min) { if (name != NULL) PyErr_Format( PyExc_TypeError, "%s expected %s%zd arguments, got %zd", name, (min == max ? "" : "at least "), min, l); else PyErr_Format( PyExc_TypeError, "unpacked tuple should have %s%zd elements," " but has %zd", (min == max ? "" : "at least "), min, l); va_end(vargs); return 0; } if (l > max) { if (name != NULL) PyErr_Format( PyExc_TypeError, "%s expected %s%zd arguments, got %zd", name, (min == max ? "" : "at most "), max, l); else PyErr_Format( PyExc_TypeError, "unpacked tuple should have %s%zd elements," " but has %zd", (min == max ? "" : "at most "), max, l); va_end(vargs); return 0; } for (i = 0; i < l; i++) { o = va_arg(vargs, PyObject **); *o = PyTuple_GET_ITEM(args, i); } va_end(vargs); return 1;} /* For type constructors that don't take keyword args * * Sets a TypeError and returns 0 if the kwds dict is * not emtpy, returns 1 otherwise */int_PyArg_NoKeywords(const char *funcname, PyObject *kw){ if (kw == NULL) return 1; if (!PyDict_CheckExact(kw)) { PyErr_BadInternalCall(); return 0; } if (PyDict_Size(kw) == 0) return 1; PyErr_Format(PyExc_TypeError, "%s does not take keyword arguments", funcname); return 0;}#ifdef __cplusplus};#endifLines 1501–1771 of 1771. Previous lines
PyObject *item; if (*format == '|') format++; item = PyDict_GetItemString(keywords, kwlist[i]); if (item != NULL) { Py_INCREF(item); msg = convertitem(item, &format, p_va, flags, levels, msgbuf, sizeof(msgbuf), &freelist); Py_DECREF(item); if (msg) { seterror(i+1, msg, levels, fname, message); return cleanreturn(0, freelist); } --nkeywords; if (nkeywords == 0) break; } else if (PyErr_Occurred()) return cleanreturn(0, freelist); else { msg = skipitem(&format, p_va, flags); if (msg) { levels[0] = 0; seterror(i+1, msg, levels, fname, message); return cleanreturn(0, freelist); } } } /* make sure there are no extraneous keyword arguments */ if (nkeywords > 0) { PyObject *key, *value; Py_ssize_t pos = 0; while (PyDict_Next(keywords, &pos, &key, &value)) { int match = 0; char *ks; if (!PyString_Check(key)) { PyErr_SetString(PyExc_TypeError, "keywords must be strings"); return cleanreturn(0, freelist); } ks = PyString_AsString(key); for (i = 0; i < max; i++) { if (!strcmp(ks, kwlist[i])) { match = 1; break; } } if (!match) { PyErr_Format(PyExc_TypeError, "'%s' is an invalid keyword " "argument for this function", ks); return cleanreturn(0, freelist); } } } return cleanreturn(1, freelist); } static char * skipitem(const char **p_format, va_list *p_va, int flags) { const char *format = *p_format; char c = *format++; switch (c) { /* simple codes * The individual types (second arg of va_arg) are irrelevant */ case 'b': /* byte -- very short int */ case 'B': /* byte as bitfield */ case 'h': /* short int */ case 'H': /* short int as bitfield */ case 'i': /* int */ case 'I': /* int sized bitfield */ case 'l': /* long int */ case 'k': /* long int sized bitfield */ #ifdef HAVE_LONG_LONG case 'L': /* PY_LONG_LONG */ case 'K': /* PY_LONG_LONG sized bitfield */ #endif case 'f': /* float */ case 'd': /* double */ #ifndef WITHOUT_COMPLEX case 'D': /* complex double */ #endif case 'c': /* char */ { (void) va_arg(*p_va, void *); break; } case 'n': /* Py_ssize_t */ { (void) va_arg(*p_va, Py_ssize_t *); break; } /* string codes */ case 'e': /* string with encoding */ { (void) va_arg(*p_va, const char *); if (!(*format == 's' || *format == 't')) /* after 'e', only 's' and 't' is allowed */ goto err; format++; /* explicit fallthrough to string cases */ } case 's': /* string */ case 'z': /* string or None */ #ifdef Py_USING_UNICODE case 'u': /* unicode string */ #endif case 't': /* buffer, read-only */ case 'w': /* buffer, read-write */ { (void) va_arg(*p_va, char **); if (*format == '#') { if (flags & FLAG_SIZE_T) (void) va_arg(*p_va, Py_ssize_t *); else (void) va_arg(*p_va, int *); format++; } break; } /* object codes */ case 'S': /* string object */ #ifdef Py_USING_UNICODE case 'U': /* unicode string object */ #endif { (void) va_arg(*p_va, PyObject **); break; } case 'O': /* object */ { if (*format == '!') { format++; (void) va_arg(*p_va, PyTypeObject*); (void) va_arg(*p_va, PyObject **); } #if 0 /* I don't know what this is for */ else if (*format == '?') { inquiry pred = va_arg(*p_va, inquiry); format++; if ((*pred)(arg)) { (void) va_arg(*p_va, PyObject **); } } #endif else if (*format == '&') { typedef int (*converter)(PyObject *, void *); (void) va_arg(*p_va, converter); (void) va_arg(*p_va, void *); format++; } else { (void) va_arg(*p_va, PyObject **); } break; } default: err: return "impossible<bad format char>"; } /* The "(...)" format code for tuples is not handled here because * it is not allowed with keyword args. */ *p_format = format; return NULL; } int PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...) { Py_ssize_t i, l; PyObject **o; va_list vargs; #ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, max); #else va_start(vargs); #endif assert(min >= 0); assert(min <= max); if (!PyTuple_Check(args)) { PyErr_SetString(PyExc_SystemError, "PyArg_UnpackTuple() argument list is not a tuple"); return 0; } l = PyTuple_GET_SIZE(args); if (l < min) { if (name != NULL) PyErr_Format( PyExc_TypeError, "%s expected %s%zd arguments, got %zd", name, (min == max ? "" : "at least "), min, l); else PyErr_Format( PyExc_TypeError, "unpacked tuple should have %s%zd elements," " but has %zd", (min == max ? "" : "at least "), min, l); va_end(vargs); return 0; } if (l > max) { if (name != NULL) PyErr_Format( PyExc_TypeError, "%s expected %s%zd arguments, got %zd", name, (min == max ? "" : "at most "), max, l); else PyErr_Format( PyExc_TypeError, "unpacked tuple should have %s%zd elements," " but has %zd", (min == max ? "" : "at most "), max, l); va_end(vargs); return 0; } for (i = 0; i < l; i++) { o = va_arg(vargs, PyObject **); *o = PyTuple_GET_ITEM(args, i); } va_end(vargs); return 1; } /* For type constructors that don't take keyword args * * Sets a TypeError and returns 0 if the kwds dict is * not emtpy, returns 1 otherwise */ int _PyArg_NoKeywords(const char *funcname, PyObject *kw) { if (kw == NULL) return 1; if (!PyDict_CheckExact(kw)) { PyErr_BadInternalCall(); return 0; } if (PyDict_Size(kw) == 0) return 1; PyErr_Format(PyExc_TypeError, "%s does not take keyword arguments", funcname); return 0; } #ifdef __cplusplus }; #endif