Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 413f013

Browse files
bpo-39904: Move handling of one-argument call of type() from type.__new__() to type.__call__(). (GH-18852)
1 parent 6012f30 commit 413f013

1 file changed

Lines changed: 32 additions & 39 deletions

File tree

Objects/typeobject.c

Lines changed: 32 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -955,35 +955,51 @@ type_repr(PyTypeObject *type)
955955
static PyObject *
956956
type_call(PyTypeObject *type, PyObject *args, PyObject *kwds)
957957
{
958+
PyObject *obj;
958959
PyThreadState *tstate = _PyThreadState_GET();
959960

960-
if (type->tp_new == NULL) {
961-
_PyErr_Format(tstate, PyExc_TypeError,
962-
"cannot create '%.100s' instances",
963-
type->tp_name);
964-
return NULL;
965-
}
966-
967961
#ifdef Py_DEBUG
968962
/* type_call() must not be called with an exception set,
969963
because it can clear it (directly or indirectly) and so the
970964
caller loses its exception */
971965
assert(!_PyErr_Occurred(tstate));
972966
#endif
973967

974-
PyObject *obj = type->tp_new(type, args, kwds);
968+
/* Special case: type(x) should return Py_TYPE(x) */
969+
/* We only want type itself to accept the one-argument form (#27157) */
970+
if (type == &PyType_Type) {
971+
assert(args != NULL && PyTuple_Check(args));
972+
assert(kwds == NULL || PyDict_Check(kwds));
973+
Py_ssize_t nargs = PyTuple_GET_SIZE(args);
974+
975+
if (nargs == 1 && (kwds == NULL || !PyDict_GET_SIZE(kwds))) {
976+
obj = (PyObject *) Py_TYPE(PyTuple_GET_ITEM(args, 0));
977+
Py_INCREF(obj);
978+
return obj;
979+
}
980+
981+
/* SF bug 475327 -- if that didn't trigger, we need 3
982+
arguments. But PyArg_ParseTuple in type_new may give
983+
a msg saying type() needs exactly 3. */
984+
if (nargs != 3) {
985+
PyErr_SetString(PyExc_TypeError,
986+
"type() takes 1 or 3 arguments");
987+
return NULL;
988+
}
989+
}
990+
991+
if (type->tp_new == NULL) {
992+
_PyErr_Format(tstate, PyExc_TypeError,
993+
"cannot create '%.100s' instances",
994+
type->tp_name);
995+
return NULL;
996+
}
997+
998+
obj = type->tp_new(type, args, kwds);
975999
obj = _Py_CheckFunctionResult(tstate, (PyObject*)type, obj, NULL);
9761000
if (obj == NULL)
9771001
return NULL;
9781002

979-
/* Ugly exception: when the call was type(something),
980-
don't call tp_init on the result. */
981-
if (type == &PyType_Type &&
982-
PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 &&
983-
(kwds == NULL ||
984-
(PyDict_Check(kwds) && PyDict_GET_SIZE(kwds) == 0)))
985-
return obj;
986-
9871003
/* If the returned object is not an instance of type,
9881004
it won't be initialized. */
9891005
if (!PyType_IsSubtype(Py_TYPE(obj), type))
@@ -2345,29 +2361,6 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
23452361
assert(args != NULL && PyTuple_Check(args));
23462362
assert(kwds == NULL || PyDict_Check(kwds));
23472363

2348-
/* Special case: type(x) should return Py_TYPE(x) */
2349-
/* We only want type itself to accept the one-argument form (#27157)
2350-
Note: We don't call PyType_CheckExact as that also allows subclasses */
2351-
if (metatype == &PyType_Type) {
2352-
const Py_ssize_t nargs = PyTuple_GET_SIZE(args);
2353-
const Py_ssize_t nkwds = kwds == NULL ? 0 : PyDict_GET_SIZE(kwds);
2354-
2355-
if (nargs == 1 && nkwds == 0) {
2356-
PyObject *x = PyTuple_GET_ITEM(args, 0);
2357-
Py_INCREF(Py_TYPE(x));
2358-
return (PyObject *) Py_TYPE(x);
2359-
}
2360-
2361-
/* SF bug 475327 -- if that didn't trigger, we need 3
2362-
arguments. but PyArg_ParseTuple below may give
2363-
a msg saying type() needs exactly 3. */
2364-
if (nargs != 3) {
2365-
PyErr_SetString(PyExc_TypeError,
2366-
"type() takes 1 or 3 arguments");
2367-
return NULL;
2368-
}
2369-
}
2370-
23712364
/* Check arguments: (name, bases, dict) */
23722365
if (!PyArg_ParseTuple(args, "UO!O!:type.__new__", &name, &PyTuple_Type,
23732366
&bases, &PyDict_Type, &orig_dict))

0 commit comments

Comments
 (0)