On Tue, Mar 1, 2016 at 11:24 AM, ast <nom...@invalid.com> wrote: > > class Premiere: > > def __new__(cls, price): > return object.__new__(cls, price) > > def __init__(self, price): > pass > > p = Premiere(1000) > > it fails. It is strange because according to me it is equivalent to: > > class Premiere: > > def __init__(self, price): > pass > > p = Premiere(1000)
The implementation knowns whether a type overrides the __new__ or __init__ methods. You're expected to consume additional arguments in this case. However, excess arguments are ignored in object.__new__ if a type overrides __init__ without overriding __new__ (i.e. your second example). Excess arguments are also ignored in object.__init__ if a type overrides __new__ without overriding __init__. In CPython, this behavior is implemented for object.__new__ by the following statement in Objects/typeobject.c, object_new: if (excess_args(args, kwds) && (type->tp_init == object_init || type->tp_new != object_new)) { PyErr_SetString(PyExc_TypeError, "object() takes no parameters"); return NULL; } An exception is always raised if a type overrides __new__ and passes extra arguments to object.__new__. No exception is raised for excess arguments in object.__new__ if a type overrides __init__ but not __new__. The __init__ method must consume the extra arguments; it must not pass them to object.__init__. The behavior for object.__init__ is implemented by the following statement in Objects/typeobject.c, object_init: 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; } An exception is always raised if a type overrides __init__ and passes extra arguments to object.__init__. No exception is raised for excess arguments in object.__init__ if a type overrides __new__ but not __init__. The __new__ method must consume the extra arguments; it must not pass them to object.__new__. -- https://mail.python.org/mailman/listinfo/python-list