On 3/21/07, Adam Olsen <[EMAIL PROTECTED]> wrote: > On 3/21/07, Jean-Paul Calderone <[EMAIL PROTECTED]> wrote: > > On Wed, 21 Mar 2007 15:45:16 -0700, Guido van Rossum <[EMAIL PROTECTED]> > > wrote: > > >See python.org/sf/1683368. I'd like to invite opinions on whether it's > > >worth breaking an unknown amount of user code in 2.6 for the sake of > > >stricter argument checking for object.__init__ and object.__new__. I > > >think it probably isn't; but the strict version could be added to 3.0 > > >and a warning issued in 2.6 in -Wpy3k mode. Alternatively, we could > > >introduce the stricter code in 2.6, fix the stdlib modules that it > > >breaks, and hope for the best. Opinions? > > > > > > > Perhaps I misunderstand the patch, but it would appear to break not just > > some inadvisable uses of super(), but an actual core feature of super(). > > Maybe someone can set me right. Is this correct? > > > > class Base(object): > > def __init__(self, important): > > # Don't upcall with `important` because object is the base > > # class and its __init__ doesn't care (or won't accept) it > > super(Base, self).__init__() > > self.a = important > > > > If so, what are the implications for this? > > > > class Other(object): > > def __init__(self, important): > > # Don't upcall with `important` because object is the base > > # class and its __init__ doesn't care (or won't accept) it > > super(Other, self).__init__() > > self.b = important > > > > class Derived(Base, Other): > > pass > > > > > > (A similar example could be given where Base and Other take differently > > named arguments with nothing to do with each other. The end result is > > the same either way, I think.) > > The common name is actually critical. Your argument names are > essentially a shared namespace, just like that on the object itself, > and they're both modifying it on the assumption of being the only > thing that does so. > > There's two ways to fix your example. First, adding a common base > class which is the "owner" of that name: > > class Owner(object): > def __init__(self, important, **kwargs): > super(Owner, self).__init__(**kwargs) # important is skipped > > class Left(Owner): > def __init__(self, important, **kwargs): > super(Left, self).__init__(important=important, **kwargs) > > class Right(Owner): > def __init__(self, important, **kwargs): > super(Right, self).__init__(important=important, **kwargs) > > class Derived(Left, Right): > pass > > >>> Derived("hi") > > > The other is to rename the argument, removing the namespace conflict: > > class Left(object): > def __init__(self, oranges, **kwargs): > super(Left, self).__init__(oranges=oranges, **kwargs) > > class Right(object): > def __init__(self, apples, **kwargs): > super(Right, self).__init__(apples=apples, **kwargs) > > class Derived(Left, Right): > pass
Hmm, where's that "undo post" button... That should be: class Left(object): def __init__(self, oranges, **kwargs): super(Left, self).__init__(**kwargs) class Right(object): def __init__(self, apples, **kwargs): super(Right, self).__init__(**kwargs) class Derived(Left, Right): pass And I would have gotten an error when I tested it had I been using the strict __init__. > > >>> Derived(apples=3, oranges=8) > > In this second version you could clean up Derived's interface by > adding either "def __init__(self, apples, oranges, **kwargs)" and > passing them both explicitly, or by adding "def __init__(self, *, > **kwargs)" and requiring they by given to you by name. Either way > you're completely safe. > > > > > > I think I understand the desire to pull keyword arguments out at each > > step of the upcalling process, but I don't see how it can work, since > > "up" calling isn't always what's going on - given a diamond, there's > > arbitrary side-calling, so for cooperation to work every method has to > > pass on every argument, so object.__init__ has to take arbitrary args, > > since no one knows when their "up" call will actually hit object. > > > > Since without diamonds, naive "by-name" upcalling works, I assume that > > super() is actually intended to be used with diamonds, so this seems > > relevant. > > > > I hope I've just overlooked something. Writing this email feels very > > strange. > > super() has always felt strange to me. Now, with PEP 3102 and the > strict __init__, not so much. > > -- > Adam Olsen, aka Rhamphoryncus > -- Adam Olsen, aka Rhamphoryncus _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com