[Python-3000] [Python-Dev] PEP 367: New Super

Tim Delaney timothy.c.delaney at gmail.com
Sat May 26 23:04:02 CEST 2007


Guido van Rossum wrote:
> Quick, since I'm about to hop on a plane: Thinking about it again,
> storing the super instance in the bound method object is fine, as long
> as you only do it when the bound function needs it. Using an unbound
> super object in an unbound method is also fine.

OTOH, I've got a counter argument to storing the super object - we don't 
want to create a permantent cycle.

If we store the class, we can store it as a weakref - the when the super 
object is created, a strong reference to the class exists.

We can't store a weakref to the super instance though, as there won't be any 
other reference to it.

I still quite like the idea of im_super though, but it would need to be a 
property instead of just a reference.

I also agree with Jim that exposing the class object is useful e.g. for 
introspection.

So I propose the following:

1. Internal weakref to class object.

2. im_type - property that returns a strong ref to the class object.

I went through several names before coming up with im_type (im_staticclass, 
im_classobj, im_classobject, im_boundclass, im_bindingclass). I think 
im_type conveys exactly what we want this attribute to represent - the 
class/type that this method was defined in.

im_class would have also been suitable, but has had another, different 
meaning since 2.2.

3. im_super - property that returns the unbound super object (for an unbound 
method) and bound super object (for a bound method).

Tim Delaney

> On 5/26/07, Tim Delaney <timothy.c.delaney at gmail.com> wrote:
>> Guido van Rossum wrote:
>>
>>>>> - Why not make super a keyword, instead of just prohibiting
>>>>> assignment to it? (I'm planning to do the same with None BTW in
>>>>> Py3k -- I find the "it's a name but you can't assign to it" a
>>>>> rather silly business and hardly "the simplest solution".)
>>>>
>>>> That's currently an open issue - I'm happy to make it a keyword -
>>>> in which case I think the title should be changed to "super as a
>>>> keyword" or something like that.
>>>
>>> As it was before. :-)
>>>
>>> What's the argument against?
>>
>> I don't see any really, especially if None is to become a true
>> keyword. But some people have raised objections.
>>
>>>> Th preamble will only be added to functions/methods that cause the
>>>> 'super' cell to exist i.e. for CPython have 'super' in co.cellvars.
>>>> Functions that just have 'super' in co.freevars wouldn't have the
>>>> preamble.
>>>
>>> I think it's still too vague. For example:
>>>
>>> class C:
>>>  def f(s):
>>>    return 1
>>> class D(C):
>>>  pass
>>> def f(s):
>>>  return 2*super.f()
>>> D.f = f
>>> print(D().f())
>>>
>>> Should that work? I would be okay if it didn't, and if the super
>>> keyword is only allowed inside a method that is lexically inside a
>>> class. Then the second definition of f() should be a (phase 2)
>>> SyntaxError.
>>
>> That would simplify things. I'll update the PEP.
>>
>>> Was it ever decided whether the implicitly bound class should be:
>>>
>>> - the class object as produced by the class statement (before
>>> applying class decorators);
>>> - whatever is returned by the last class decorator (if any); or
>>> - whatever is bound to the class name at the time the method is
>>> invoked?
>>> I've got a hunch that #1 might be more solid; #3 seems asking for
>>> trouble.
>>
>> I think #3 is definitely the wrong thing to do, but there have been
>> arguments put forwards for both #1 and #2.
>>
>> I think I'll put it as an open issue for now.
>>
>>> There's also the issue of what to do when the method itself is
>>> decorated (the compiler can't know what the decorators mean, even
>>> for built-in decorators like classmethod).
>>
>> I think that may be a different issue. If you do something like:
>>
>> class A:
>>     @decorator
>>     def func(self):
>>         pass
>>
>> class B(A):
>>     @decorator
>>     def func(self):
>>         super.func()
>>
>> then `super.func()` will call whatever `super(B, self).func()` would
>> now, which (I think) would result in calling the decorated function.
>>
>> However, I think the staticmethod decorator would need to be able to
>> modify the class instance that's held by the method. Or see my
>> proposal below ...
>>> We could make the class in question a fourth attribute of the
>>> (poorly named) "bound method" object, e.g. im_class_for_super
>>> (im_super would be confusing IMO). Since this is used both by
>>> instance methods and by the @classmethod decorator, it's just about
>>> perfect for this purpose. (I would almost propose to reuse im_self
>>> for this purpose, but that's probably asking for subtle backwards
>>> incompatibilities and not worth it.)
>>
>> I'm actually thinking instead that an unbound method should
>> reference an unbound super instance for the appropriate class -
>> which we could then call im_super.
>>
>> For a bound instance or class method, im_super would return the
>> appropriate bound super instance. In practice, it would work like
>> your autosuper recipe using __super.
>>
>> e.g.
>>
>> class A:
>>     def func(self):
>>         pass
>>
>>>>> print A.func.im_super
>> <super: <class 'A'>, NULL>
>>
>>>>> print A().func.im_super
>> <super: <class 'A'>, <A object>>
>>
>>> See my proposal above. It differs slightly in that the __super__
>>> call is made only when the class is not NULL. On the expectation
>>> that a typical function that references super uses it exactly once
>>> per call (that would be by far the most common case I expect) this
>>> is just fine. In my proposal the 'super' variable contains whatever
>>> __super__(<class>, <inst>) returned, rather than <class> which you
>>> seem to be proposing here.
>>
>> Think I must have been explaining poorly - if you look at the
>> reference implementation in the PEP, you'll see that that's exactly
>> what's held in the 'super' free variable.
>>
>> I think your proposal is basically what I was trying to convey -
>> I'll look at rewording the PEP so it's less ambiguous. But I'd like
>> your thoughts on the above proposal to keep a reference to the
>> actual super object rather than the class.
>>
>> Cheers,
>>
>> Tim Delaney 



More information about the Python-3000 mailing list