[Python-Dev] New Super PEP

Calvin Spealman ironfroggy at gmail.com
Sun Apr 29 15:29:43 CEST 2007


Yes, I bad wordly things did. Fix will I.

On 4/29/07, Talin <talin at acm.org> wrote:
> Calvin Spealman wrote:
> > Comments welcome, of course. Bare with my first attempt at crafting a PEP.
>
> See below for comments; In general, I'm having problems understanding
> some of the terms used. I don't have any comments on the technical
> merits of the PEP yet, since I don't completely understand what is being
> said.
>
> > PEP: XXX
> > Title: Super As A Keyword
> > Version: $Revision$
> > Last-Modified: $Date$
> > Author: Calvin Spealman <ironfroggy at gmail.com>
> > Status: Draft
> > Type: Standards Track
> > Content-Type: text/x-rst
> > Created: 30-Apr-2007
> > Python-Version: 2.6
> > Post-History:
> >
> >
> > Abstract
> > ========
> >
> > The PEP defines the proposal to enhance the super builtin to work implicitly
> > upon the class within which it is used and upon the instance the current
> > function was called on. The premise of the new super usage suggested is as
> > follows:
> >
> >     super.foo(1, 2)
> >
> > to replace the old:
> >
> >     super(Foo, self).foo(1, 2)
> >
> >
> > Rationale
> > =========
> >
> > The current usage of super requires an explicit passing of both the class and
> > instance it must operate from, requiring a breaking of the DRY (Don't Repeat
> > Yourself) rule. This hinders any change in class name, and is often considered
> > a wart by many.
> >
> >
> > Specification
> > =============
> >
> > Replacing the old usage of super, calls to the next class in the MRO (method
> > resolution order) will be made without an explicit super object creation,
> > by simply accessing an attribute on the super type directly, which will
> > automatically apply the class and instance to perform the proper lookup. The
> > following example demonstrates the use of this.
>
> I don't understand the phrase 'by simply accessing an attribute on the
> super type directly'. See below for for more detail.
>
> >     ::
> >
> >         class A(object):
> >             def f(self):
> >                 return 'A'
> >
> >         class B(A):
> >             def f(self):
> >                 return 'B' + super.f()
> >
> >         class C(A):
> >             def f(self):
> >                 return 'C' + super.f()
> >
> >         class D(B, C):
> >             def f(self):
> >                 return 'D' + super.f()
> >
> >         assert D().f() == 'DBCA'
> >
>
> The example is clear enough.
>
> > The proposal adds a dynamic attribute lookup to the super type, which will
> > automatically determine the proper class and instance parameters. Each super
> > attribute lookup identifies these parameters and performs the super lookup on
> > the instance, as the current super implementation does with the explicit
> > invokation of a super object upon a class and instance.
>
> When you say 'the super type' I'm not sure what you mean. Do you mean
> the next class in the MRO, or the base class in which the super method
> is defined? Or something else? What defines the 'proper' class?

There is some ambiguous nature there that I missed. I think I used the
same term for both the super type, as in the actual builtin type named
"super" and to refer to the next type in the MRO order after the
current type. What proper terminology would differentiate?

> Can we have a definition of what a "super object" is?

An instance of the builtin type named "super". Something for which
isinstance(o, super) is True.

> > The enhancements to the super type will define a new __getattr__ classmethod
> > of the super type, which must look backwards to the previous frame and locate
> > the instance object. This can be naively determined by located the local named
> > by the first argument to the function. Using super outside of a function where
> > this is a valid lookup for the instance can be considered undocumented in its
> > behavior.
>
> As I am reading this I get the impression that the phrase 'the super
> type' is actually referring to the 'super' keyword itself - for example,
>   you say that the super type has a new __getattr__ classmethod, which I
> read as saying that you can now say "super.x".

Yes.

> > Every class will gain a new special attribute, __super__, which is a super
> > object instansiated only with the class it is an attribute of. In this
> > capacity, the new super also acts as its own descriptor, create an instance-
> > specific super upon lookup.
>
> I'm trying to parse that first sentence. How about "Every class will
> gain a new special attribute, __super__, which refers to an instance of
> the associated super object for that class".

Check.

> What does the phrase 'the new super' refer to - they keyword 'super',
> the super type, or the super object?

"the new super" refers to the updated super type this PEP proposes.
Instances of the new super type will act as their own descriptors,
which is how they are bound to specific instances of the classes they
are associated with.

> > Much of this was discussed in the thread of the python-dev list, "Fixing super
> > anyone?" [1]_.
> >
> > Open Issues
> > -----------
> >
> > __call__ methods
> > ''''''''''''''''
> >
> > Backward compatability of the super type API raises some issues. Names, the
> > lookup of the __call__ of the super type itself, which means a conflict with
> > doing an actual super lookup of the __call__ attribute. Namely, the following
> > is ambiguous in the current proposal:
> >
> >     ::
> >
> >         super.__call__(arg)
> >
> > Which means the backward compatible API, which involves instansiating the super
> > type, will either not be possible, because it will actually do a super lookup
> > on the __call__ attribute, or there will be no way to perform a super lookup on
> > the __call__ attribute. Both seem unacceptable, so any suggestions are welcome.
> >
> > super type's new getattr
> > ''''''''''''''''''''''''
> >
> > To give the behavior needed, the super type either needs a way to do dynamic
> > lookup of attributes on the super type object itself or define a metaclass for
> > the builtin type. This author is unsure which, if either, is possible with C-
> > defined types.
> >
> > When should we create __super__ attributes?
> > '''''''''''''''''''''''''''''''''''''''''''
> >
> > They either need to be created on class creation or on __super__ attribute
> > lookup. For the second, they could be cached, of course, which seems like it
> > may be the best idea, if implicit creation of a super object for every class is
> > considered too much overhead.
> >
> >
> > References
> > ==========
> >
> > .. [1] Fixing super anyone?
> >    (http://mail.python.org/pipermail/python-3000/2007-April/006667.html)
> >
> >
> > Copyright
> > =========
> >
> > This document has been placed in the public domain.
> >
> >
> >
> > ..
> >    Local Variables:
> >    mode: indented-text
> >    indent-tabs-mode: nil
> >    sentence-end-double-space: t
> >    fill-column: 70
> >    coding: utf-8
> >    End:
> >
> >
>

I'll also add a section on alternate proposals. I'll look through the
"Fixing super anyone?" thread for them, but are there any others I
might not be aware of? If anyone has a suggestion for an alternative
proposal that deserves documenting, let me know.

I'll make the changes needed, and try to clarify the language more.
Maybe It was too late when I wrote this.

On 4/29/07, Collin Winter <collinw at gmail.com> wrote:
> On 4/28/07, Calvin Spealman <ironfroggy at gmail.com> wrote:
> > Comments welcome, of course. Bare with my first attempt at crafting a PEP.
> > Which means the backward compatible API, which involves instansiating the super
> > type, will either not be possible, because it will actually do a super lookup
> > on the __call__ attribute, or there will be no way to perform a super lookup on
> > the __call__ attribute. Both seem unacceptable, so any suggestions are welcome.
>
> You're offering absolutely zero backwards compatibility and you're
> targeting 2.6? Um, no; absolutely not. Even if you intend this for
> 3.0, you'll still need to define either a backwards compatibility
> solution or a migration strategy (e.g., a 2to3 fixer). Without a
> clear-cut way of addressing existing code, this idea is toast.

Obviously its probably the biggest problem. I'm not positive this
should target 2.6, no one really seemed to mention a version in the
previous discussions. This is specifically syntax that Guido said he
wanted a way to do, and with backward compatibility. I would
absolutely love for someone to figure out how to solve the __call__
problem, but I don't know how to do it without weakening either
strategy.

The super type itself needs changed for this to work, so maybe we can
keep the old one around in 2.6, add a future import to bind the super
name to the new version, and make the new version default in 3.0? That
would let us have backwards compatibility without the two types
interfering with each other, and simplify the implementation greatly.

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


More information about the Python-Dev mailing list