]> granicus.if.org Git - python/commitdiff
SF bug #475327: type() produces incorrect error msg
authorTim Peters <tim.peters@gmail.com>
Sat, 27 Oct 2001 19:37:48 +0000 (19:37 +0000)
committerTim Peters <tim.peters@gmail.com>
Sat, 27 Oct 2001 19:37:48 +0000 (19:37 +0000)
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
Objects/typeobject.c

index c565fbe92010d8db6d9ea1da053141863022cf02..52d6dbf6288d3e7230271f56e09cbf0935b8bd5a 100644 (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);
index ba2834a08bfbca82b6e1ea6a8ae3b2d52068f09a..026fe1496730f080d62cc7be40abeaeb2d8293de 100644 (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) */