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.
This commit is contained in:
Tim Peters 2001-10-27 19:37:48 +00:00
parent 4d85953fe6
commit 3abca127fe
2 changed files with 22 additions and 6 deletions

View File

@ -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);

View File

@ -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) */