Issue #27157: Make only type() itself accept the one-argument form

Patch by Eryk Sun and Emanuel Barry.
This commit is contained in:
Berker Peksag 2016-08-19 11:04:07 +03:00
parent 2a400fd62a
commit 3f015a64b8
4 changed files with 30 additions and 4 deletions

View file

@ -2287,11 +2287,13 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
assert(kwds == NULL || PyDict_Check(kwds));
/* Special case: type(x) should return x->ob_type */
{
/* We only want type itself to accept the one-argument form (#27157)
Note: We don't call PyType_CheckExact as that also allows subclasses */
if (metatype == &PyType_Type) {
const Py_ssize_t nargs = PyTuple_GET_SIZE(args);
const Py_ssize_t nkwds = kwds == NULL ? 0 : PyDict_Size(kwds);
if (PyType_CheckExact(metatype) && nargs == 1 && nkwds == 0) {
if (nargs == 1 && nkwds == 0) {
PyObject *x = PyTuple_GET_ITEM(args, 0);
Py_INCREF(Py_TYPE(x));
return (PyObject *) Py_TYPE(x);
@ -2308,8 +2310,8 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
}
/* Check arguments: (name, bases, dict) */
if (!PyArg_ParseTuple(args, "UO!O!:type", &name, &PyTuple_Type, &bases,
&PyDict_Type, &orig_dict))
if (!PyArg_ParseTuple(args, "UO!O!:type.__new__", &name, &PyTuple_Type,
&bases, &PyDict_Type, &orig_dict))
return NULL;
/* Determine the proper metatype to deal with this: */