On 3/1/2016 12:24 PM, ast wrote:
Hello

It's not clear to me what arguments are passed to the
__new__ method.

The objects passed to any function are the objects that are passed. The type and number of objects that *should be* passed depends on the signature of the function.

If class C defines __new__, then C.__new__ will receive as args C and all args passed in a C(...) call. So the C(...) call should have args that match those expected by __new__. If C also defines __init__, it will get the same args other than self replacing cls and thus it should have the same signature.

The case is covered by in the entry for __new__ in
https://docs.python.org/3/reference/datamodel.html#basic-customization

"If __new__() returns an instance of cls, then the new instance’s __init__() method will be invoked like __init__(self[, ...]), where self is the new instance and the remaining arguments are the same as were passed to __new__()."

class Premiere:
    def __new__(cls, price):
         return object.__new__(cls)

This matches "Typical implementations create a new instance of the class by invoking the superclass’s __new__() method using super(currentclass, cls).__new__(cls[, ...]) with appropriate arguments and then modifying the newly-created instance as necessary before returning it." object.__new__ only takes the cls parameter.

    def __init__(self, price):
            pass
p = Premiere(1000)

No errors, so it seems that 2 arguments are passed
to __new__, cls and price,

and 2 arguments are passed to __init__, self and price -- as documented.

But if i do:

class Premiere:
    def __new__(cls, price):
        return object.__new__(cls, price)

You get an error in current python because you sent an extra arg to object.__new__. If __new__ calls a superclass __new__, then it should only pass the args expected. At one time, object.__new__ would have accepted the price arg and ignored it. This is no longer true

    def __init__(self, price):
        pass
p = Premiere(1000)

it fails. It is strange because according to me it is equivalent to:

Well, 'you' is wrong ;-), because in the following case, Premiere.__new__ is object.__new__, which has a different signature than __new__ above.

class Premiere:
    def __init__(self, price):
         pass
p = Premiere(1000)

which is OK.

Premiere is callable because it inherits object.__call__. That function, or the implementation of the CALL FUNCTION bytecode, must notice that Premiere.__new__ is object.__new__, by inheritance, and only pass Premiere and not 1000.

The doc entry for __init__ says "The arguments are those passed to the class constructor expression." (The latter is the expression in the code that results in the class call.) This is always true. But since the signature of object.__new__ was restricted, the claim that the same args are sent to __new__ and __init__ seems not to be true.

I may open a new doc issue.

--
Terry Jan Reedy


--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to