summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2001-10-27 19:37:48 (GMT)
committerTim Peters <tim.peters@gmail.com>2001-10-27 19:37:48 (GMT)
commit3abca127fe1565ec80f6b0a1ae48d65186ad887d (patch)
treead9da6a32fe9956cba5d804939f345b85ad85259
parent4d85953fe609197c54827826963eabaf6418024c (diff)
downloadcpython-3abca127fe1565ec80f6b0a1ae48d65186ad887d.zip
cpython-3abca127fe1565ec80f6b0a1ae48d65186ad887d.tar.gz
cpython-3abca127fe1565ec80f6b0a1ae48d65186ad887d.tar.bz2
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.
-rw-r--r--Include/object.h1
-rw-r--r--Objects/typeobject.c27
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) */