mirror of
https://github.com/python/cpython.git
synced 2025-07-23 11:15:24 +00:00
Issue #27157: Make only type() itself accept the one-argument form
Patch by Eryk Sun and Emanuel Barry.
This commit is contained in:
parent
2a400fd62a
commit
3f015a64b8
4 changed files with 30 additions and 4 deletions
|
@ -1463,6 +1463,9 @@ are always available. They are listed here in alphabetical order.
|
|||
|
||||
See also :ref:`bltin-type-objects`.
|
||||
|
||||
.. versionchanged:: 3.6
|
||||
Subclasses of :class:`type` which don't override ``type.__new__`` may no
|
||||
longer use the one-argument form to get the type of an object.
|
||||
|
||||
.. function:: vars([object])
|
||||
|
||||
|
|
|
@ -1000,6 +1000,24 @@ class ClassCreationTests(unittest.TestCase):
|
|||
with self.assertRaises(TypeError):
|
||||
X = types.new_class("X", (int(), C))
|
||||
|
||||
def test_one_argument_type(self):
|
||||
expected_message = 'type.__new__() takes exactly 3 arguments (1 given)'
|
||||
|
||||
# Only type itself can use the one-argument form (#27157)
|
||||
self.assertIs(type(5), int)
|
||||
|
||||
class M(type):
|
||||
pass
|
||||
with self.assertRaises(TypeError) as cm:
|
||||
M(5)
|
||||
self.assertEqual(str(cm.exception), expected_message)
|
||||
|
||||
class N(type, metaclass=M):
|
||||
pass
|
||||
with self.assertRaises(TypeError) as cm:
|
||||
N(5)
|
||||
self.assertEqual(str(cm.exception), expected_message)
|
||||
|
||||
|
||||
class SimpleNamespaceTests(unittest.TestCase):
|
||||
|
||||
|
|
|
@ -10,6 +10,9 @@ What's New in Python 3.6.0 beta 1
|
|||
Core and Builtins
|
||||
-----------------
|
||||
|
||||
- Issue #27157: Make only type() itself accept the one-argument form.
|
||||
Patch by Eryk Sun and Emanuel Barry.
|
||||
|
||||
- Issue #27558: Fix a SystemError in the implementation of "raise" statement.
|
||||
In a brand new thread, raise a RuntimeError since there is no active
|
||||
exception to reraise. Patch written by Xiang Zhang.
|
||||
|
|
|
@ -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: */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue