[Python-3000] Fixing super anyone?

Calvin Spealman ironfroggy at gmail.com
Tue Apr 24 06:11:01 CEST 2007


On 4/23/07, Jim Jewett <jimjjewett at gmail.com> wrote:
> On 4/23/07, Michele Cella <michele.cella at gmail.com> wrote:
>
> > ... having a super keyword with methods attached ... doesn't feel right
>
> Agreed.  The goal is to *fix* super, not to make it a keyword.  Making
> it a keyword might -- or might not -- be the way to do that.  A
> keyword with attributes is probably not the right answer.
>
> For What Its Worth, the longer I think about this, the more convinced
> I am that the right answer is to keep it an object.  The problem is
> that it has to grow even more magical than it already is, unless we
> break a lot of backwards compatibility.
>
> If we're willing to put up with the magic, then it would work to make
> super syntactic sugar for
>
>     super(__this_class__, self)
>
> At the moment, I can't see anything wrong with this, but I have a
> feeling I'm missing something about how the super object should behave
> on its own.  Is there a good way (other than "being inside a method"?)
> to distinguish between:
>
>     super.__str__()     # I want to call the super-class' str method
>
> and
>
>     super.__str__()     # I want to call str(super)
>
>
>
> > The only other option that comes to my mind is using a special attribute
> > in the instance itself (like __class__, __dict__, ...):
>
> >         self.__super__.mymethod(arg)
>
> __class__ and __dict__ are (sort of) ordinary attributes -- they point
> to a specific object.  super would probably need to be an active
> property.
>
>     class A: ...
>     class B1(A): ...
>     class C1(B1): ...
>     class B2(A): ...
>     class C2(B1): ...
>
>     class D(C1, C2): ...
>     class E(D): ...
>
> When an instance of E is created, the super call may well be made in
> D, so you don't know the instance's class when compiling the code.
>
> When methods in B1 make a super call for "normal" instances of C1,
> they go straight to class A.  But if the instance is really an
> instance of E, then they first have to loop back through C2 and C1.
> So when compiling the class, you don't know which class will be next
> in the mro.
>
> So you can't do it from the class -- but you also can't do it only
> from the instance.  For an instance of E, super(C1, self) and
> super(B2, self) should go to different next-classes.
>
> So you need both the instance's own true class, and the class where
> the current method was defined -- but even that isn't quite enough.
> You can't quite say "next in the instance's mro", because if the
> method happens to be something that C2 doesn't override, then super(D,
> self) should go straight to C1 -- but it still needs to look at C2 for
> other methods.
>
> -jJ
> _______________________________________________
> Python-3000 mailing list
> Python-3000 at python.org
> http://mail.python.org/mailman/listinfo/python-3000
> Unsubscribe: http://mail.python.org/mailman/options/python-3000/ironfroggy%40gmail.com
>

I will +1 on the self.__super__ suggestion. Hey, its very doable and I
even whipped it up with a simple metaclass, so it would be a tiny
change to 'type' in order to actually implement it as a standard
feature. The demonstration is as follows:

class _superdesc(object):
    def __get__(self, obj, objcls):
        return super(cls, obj)

class autosuper(type):
    def __init__(cls, name, bases, clsdict):
        cls.__super__ = _superdesc()

class A(object):
    __metaclass__ = autosuper
    x = 1

class B(A):
    x = 2

assert B().__super__.x == 1

-- 
Read my blog! I depend on your acceptance of my opinion! I am interesting!
http://ironfroggy-code.blogspot.com/


More information about the Python-3000 mailing list