From 96384b93aae1d1e45dda21c4024d7d083c91626d Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 17 Mar 2012 00:05:44 -0500 Subject: [PATCH] make extra arguments to object.__init__/__new__ to errors in most cases (finishes #1683368) --- Lib/test/test_descr.py | 20 +++++++++++++++++++ Misc/NEWS | 3 +++ Objects/typeobject.c | 45 ++++++++++-------------------------------- 3 files changed, 33 insertions(+), 35 deletions(-) diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index bf82a889e1c..5759effca71 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -4502,6 +4502,26 @@ order (MRO) for bases """ for o in gc.get_objects(): self.assertIsNot(type(o), X) + def test_object_new_and_init_with_parameters(self): + # See issue #1683368 + class OverrideNeither: + pass + self.assertRaises(TypeError, OverrideNeither, 1) + self.assertRaises(TypeError, OverrideNeither, kw=1) + class OverrideNew: + def __new__(cls, foo, kw=0, *args, **kwds): + return object.__new__(cls, *args, **kwds) + class OverrideInit: + def __init__(self, foo, kw=0, *args, **kwargs): + return object.__init__(self, *args, **kwargs) + class OverrideBoth(OverrideNew, OverrideInit): + pass + for case in OverrideNew, OverrideInit, OverrideBoth: + case(1) + case(1, kw=2) + self.assertRaises(TypeError, case, 1, 2, 3) + self.assertRaises(TypeError, case, 1, 2, foo=3) + class DictProxyTests(unittest.TestCase): def setUp(self): diff --git a/Misc/NEWS b/Misc/NEWS index 5672fc31d16..095bfc8a157 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ What's New in Python 3.3.0 Alpha 2? Core and Builtins ----------------- +- Issue #1683368: object.__new__ and object.__init__ raise a TypeError if they + are passed arguments and their complementary method is not overridden. + - Give the ast.AST class a __dict__. - Issue #14334: Prevent in a segfault in type.__getattribute__ when it was not diff --git a/Objects/typeobject.c b/Objects/typeobject.c index b427040fbc3..5fbd7cb8d31 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2905,22 +2905,11 @@ static int object_init(PyObject *self, PyObject *args, PyObject *kwds) { int err = 0; - if (excess_args(args, kwds)) { - PyTypeObject *type = Py_TYPE(self); - if (type->tp_init != object_init && - type->tp_new != object_new) - { - err = PyErr_WarnEx(PyExc_DeprecationWarning, - "object.__init__() takes no parameters", - 1); - } - else if (type->tp_init != object_init || - type->tp_new == object_new) - { - PyErr_SetString(PyExc_TypeError, - "object.__init__() takes no parameters"); - err = -1; - } + PyTypeObject *type = Py_TYPE(self); + if (excess_args(args, kwds) && + (type->tp_new == object_new || type->tp_init != object_init)) { + PyErr_SetString(PyExc_TypeError, "object.__init__() takes no parameters"); + err = -1; } return err; } @@ -2928,26 +2917,12 @@ object_init(PyObject *self, PyObject *args, PyObject *kwds) static PyObject * object_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - int err = 0; - if (excess_args(args, kwds)) { - if (type->tp_new != object_new && - type->tp_init != object_init) - { - err = PyErr_WarnEx(PyExc_DeprecationWarning, - "object.__new__() takes no parameters", - 1); - } - else if (type->tp_new != object_new || - type->tp_init == object_init) - { - PyErr_SetString(PyExc_TypeError, - "object.__new__() takes no parameters"); - err = -1; - } - } - if (err < 0) + if (excess_args(args, kwds) && + (type->tp_init == object_init || type->tp_new != object_new)) { + PyErr_SetString(PyExc_TypeError, "object.__new__() takes no parameters"); return NULL; - + } + if (type->tp_flags & Py_TPFLAGS_IS_ABSTRACT) { PyObject *abstract_methods = NULL; PyObject *builtins;