What arguments are passed to the __new__ method ?

eryk sun eryksun at gmail.com
Tue Mar 1 14:54:31 EST 2016


On Tue, Mar 1, 2016 at 11:24 AM, ast <nomail at 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__.



More information about the Python-list mailing list