[Python-Dev] Breaking calls to object.__init__/__new__

Jean-Paul Calderone exarkun at divmod.com
Thu Mar 22 02:54:16 CET 2007


On Wed, 21 Mar 2007 15:45:16 -0700, Guido van Rossum <guido at python.org> 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.)

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.

Jean-Paul


More information about the Python-Dev mailing list