From 3abca127fe1565ec80f6b0a1ae48d65186ad887d Mon Sep 17 00:00:00 2001 From: Tim Peters Date: Sat, 27 Oct 2001 19:37:48 +0000 Subject: SF bug #475327: type() produces incorrect error msg object.h: Added PyType_CheckExact macro. typeobject.c, type_new(): + Use the new macro. + Assert that the arguments have the right types rather than do incomplete runtime checks "sometimes". + If this isn't the 1-argument flavor() of type, and there aren't 3 args total, produce a "types() takes 1 or 3 args" msg before PyArg_ParseTupleAndKeywords produces a "takes exactly 3" msg. --- Include/object.h | 1 + Objects/typeobject.c | 27 +++++++++++++++++++++------ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/Include/object.h b/Include/object.h index c565fbe..52d6dbf 100644 --- a/Include/object.h +++ b/Include/object.h @@ -312,6 +312,7 @@ extern DL_IMPORT(PyTypeObject) PyBaseObject_Type; /* built-in 'object' */ extern DL_IMPORT(PyTypeObject) PySuper_Type; /* built-in 'super' */ #define PyType_Check(op) PyObject_TypeCheck(op, &PyType_Type) +#define PyType_CheckExact(op) ((op)->ob_type == &PyType_Type) extern DL_IMPORT(int) PyType_Ready(PyTypeObject *); extern DL_IMPORT(PyObject *) PyType_GenericAlloc(PyTypeObject *, int); diff --git a/Objects/typeobject.c b/Objects/typeobject.c index ba2834a..026fe14 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -713,13 +713,28 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) PyMemberDef *mp; int i, nbases, nslots, slotoffset, add_dict, add_weak; + assert(args != NULL && PyTuple_Check(args)); + assert(kwds == NULL || PyDict_Check(kwds)); + /* Special case: type(x) should return x->ob_type */ - if (metatype == &PyType_Type && - PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 && - (kwds == NULL || (PyDict_Check(kwds) && PyDict_Size(kwds) == 0))) { - PyObject *x = PyTuple_GET_ITEM(args, 0); - Py_INCREF(x->ob_type); - return (PyObject *) x->ob_type; + { + const int nargs = PyTuple_GET_SIZE(args); + const int nkwds = kwds == NULL ? 0 : PyDict_Size(kwds); + + if (PyType_CheckExact(metatype) && nargs == 1 && nkwds == 0) { + PyObject *x = PyTuple_GET_ITEM(args, 0); + Py_INCREF(x->ob_type); + return (PyObject *) x->ob_type; + } + + /* SF bug 475327 -- if that didn't trigger, we need 3 + arguments. but PyArg_ParseTupleAndKeywords below may give + a msg saying type() needs exactly 3. */ + if (nargs + nkwds != 3) { + PyErr_SetString(PyExc_TypeError, + "type() takes 1 or 3 arguments"); + return NULL; + } } /* Check arguments: (name, bases, dict) */ -- cgit v0.12