On Fri, Nov 9, 2012 at 4:37 AM, Steven D'Aprano <steve+comp.lang.pyt...@pearwood.info> wrote: > In Python 3.3: > > py> class X(int): > ... def __init__(self, *args): > ... super().__init__(*args) # does nothing, call it anyway > ... > py> x = X(22) > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > File "<stdin>", line 3, in __init__ > TypeError: object.__init__() takes no parameters > > > It is apparently an oversight, or a bug, that it ever worked in older > versions.
After reading through the bug history, I think that this change to int is incorrect, or at least incomplete. The goal of the change to object.__init__ is to enable checking for unused arguments when doing cooperative multiple inheritance, with the idea that each class in the hierarchy will remove the arguments it uses and pass the rest along. By the time object.__init__ is reached, any arguments remaining are unused and extraneous. In the case of int, int.__new__ takes up to two arguments. Due to the nature of the type system, these same two arguments are also passed to int.__init__. If each subclass removes its own arguments per the convention, then by the time int.__init__ is reached, there are still up to two *expected* arguments remaining. It should not be the responsibility of the subclasses (which one? all of them?) to remove these arguments before calling super().__init__(). The int class should have the responsibility of accepting and removing these two arguments *and then* checking that there is nothing left over. In Python 3.2, int.__init__ happily accepted the int arguments, but also incorrectly accepted anything else you might pass to it, which was suboptimal for cooperative multiple inheritance. In Python 3.3, it no longer accepts unused arguments, but it also rejects arguments intended for its own class that it should accept, which as I see it makes int.__init__ *unusable* for cooperative multiple inheritance. I realize that the recommendation in the bug comments is to use __new__ instead of __init__ for subclasses of immutable types. But then why have them call __init__ in the first place? Why even fuss over what arguments int.__init__ does or does not accept if we're not supposed to be calling it at all? And why is that deprecation not mentioned anywhere in the documentation, that I can find? -- http://mail.python.org/mailman/listinfo/python-list