238 lines
7.8 KiB
Plaintext
238 lines
7.8 KiB
Plaintext
PEP: 3135
|
||
Title: New Super
|
||
Version: $Revision$
|
||
Last-Modified: $Date$
|
||
Author: Calvin Spealman <ironfroggy@gmail.com>,
|
||
Tim Delaney <timothy.c.delaney@gmail.com>,
|
||
Lie Ryan <lie.1296@gmail.com>
|
||
Status: Final
|
||
Type: Standards Track
|
||
Content-Type: text/x-rst
|
||
Created: 28-Apr-2007
|
||
Python-Version: 3.0
|
||
Post-History: `28-Apr-2007 <https://mail.python.org/pipermail/python-dev/2007-April/072807.html>`__,
|
||
`29-Apr-2007 <https://mail.python.org/pipermail/python-dev/2007-April/072835.html>`__,
|
||
`29-Apr-2007 <https://mail.python.org/pipermail/python-dev/2007-April/072858.html>`__,
|
||
`14-May-2007 <https://mail.python.org/pipermail/python-dev/2007-May/073127.html>`__,
|
||
`12-Mar-2009 <https://mail.python.org/pipermail/python-bugs-list/2009-March/072665.html>`__
|
||
|
||
Numbering Note
|
||
==============
|
||
|
||
This PEP started its life as :pep:`367`. Since it is now targeted
|
||
for Python 3000, it has been moved into the 3xxx space.
|
||
|
||
Abstract
|
||
========
|
||
|
||
This PEP proposes syntactic sugar for use of the ``super`` type to automatically
|
||
construct instances of the super type binding to the class that a method was
|
||
defined in, and the instance (or class object for classmethods) that the method
|
||
is currently acting upon.
|
||
|
||
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
|
||
=============
|
||
|
||
Within the specification section, some special terminology will be used to
|
||
distinguish similar and closely related concepts. "super class" will refer to
|
||
the actual builtin class named "super". A "super instance" is simply an
|
||
instance of the super class, which is associated with another class and
|
||
possibly with an instance of that class.
|
||
|
||
The new ``super`` semantics are only available in Python 3.0.
|
||
|
||
Replacing the old usage of super, calls to the next class in the MRO (method
|
||
resolution order) can be made without explicitly passing the class object
|
||
(although doing so will still be supported). Every function
|
||
will have a cell named ``__class__`` that contains the class object that the
|
||
function is defined in.
|
||
|
||
The new syntax::
|
||
|
||
super()
|
||
|
||
is equivalent to::
|
||
|
||
super(__class__, <firstarg>)
|
||
|
||
where ``__class__`` is the class that the method was defined in, and
|
||
``<firstarg>`` is the first parameter of the method (normally ``self``
|
||
for instance methods, and ``cls`` for class methods). For functions
|
||
defined outside a class body, ``__class__`` is not defined, and will
|
||
result in runtime ``SystemError``.
|
||
|
||
While ``super`` is not a reserved word, the parser recognizes the use
|
||
of ``super`` in a method definition and only passes in the
|
||
``__class__`` cell when this is found. Thus, calling a global alias
|
||
of ``super`` without arguments will not necessarily work.
|
||
|
||
Closed Issues
|
||
=============
|
||
|
||
Determining the class object to use
|
||
-----------------------------------
|
||
|
||
The class object is taken from a cell named ``__class__``.
|
||
|
||
|
||
Should ``super`` actually become a keyword?
|
||
-------------------------------------------
|
||
|
||
No. It is not necessary for super to become a keyword.
|
||
|
||
super used with __call__ attributes
|
||
-----------------------------------
|
||
|
||
It was considered that it might be a problem that instantiating super instances
|
||
the classic way, because calling it would lookup the __call__ attribute and
|
||
thus try to perform an automatic super lookup to the next class in the MRO.
|
||
However, this was found to be false, because calling an object only looks up
|
||
the __call__ method directly on the object's type. The following example shows
|
||
this in action.
|
||
|
||
::
|
||
|
||
class A(object):
|
||
def __call__(self):
|
||
return '__call__'
|
||
def __getattribute__(self, attr):
|
||
if attr == '__call__':
|
||
return lambda: '__getattribute__'
|
||
a = A()
|
||
assert a() == '__call__'
|
||
assert a.__call__() == '__getattribute__'
|
||
|
||
In any case, this issue goes away entirely because classic calls to
|
||
``super(<class>, <instance>)`` are still supported with the same meaning.
|
||
|
||
Alternative Proposals
|
||
=====================
|
||
|
||
No Changes
|
||
----------
|
||
|
||
Although its always attractive to just keep things how they are, people have
|
||
sought a change in the usage of super calling for some time, and for good
|
||
reason, all mentioned previously.
|
||
|
||
- Decoupling from the class name (which might not even be bound to the
|
||
right class anymore!)
|
||
- Simpler looking, cleaner super calls would be better
|
||
|
||
Dynamic attribute on super type
|
||
-------------------------------
|
||
|
||
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
|
||
invocation of a super instance upon a class and instance.
|
||
|
||
This proposal relies on sys._getframe(), which is not appropriate for anything
|
||
except a prototype implementation.
|
||
|
||
self.__super__.foo(\*args)
|
||
--------------------------
|
||
|
||
The __super__ attribute is mentioned in this PEP in several places, and could
|
||
be a candidate for the complete solution, actually using it explicitly instead
|
||
of any super usage directly. However, double-underscore names are usually an
|
||
internal detail, and attempted to be kept out of everyday code.
|
||
|
||
super(self, \*args) or __super__(self, \*args)
|
||
----------------------------------------------
|
||
|
||
This solution only solves the problem of the type indication, does not handle
|
||
differently named super methods, and is explicit about the name of the
|
||
instance. It is less flexible without being able to enacted on other method
|
||
names, in cases where that is needed. One use case this fails is where a base-
|
||
class has a factory classmethod and a subclass has two factory classmethods,
|
||
both of which needing to properly make super calls to the one in the base-
|
||
class.
|
||
|
||
super.foo(self, \*args)
|
||
-----------------------
|
||
|
||
This variation actually eliminates the problems with locating the proper
|
||
instance, and if any of the alternatives were pushed into the spotlight, I
|
||
would want it to be this one.
|
||
|
||
super(\*p, \*\*kw)
|
||
------------------
|
||
|
||
There has been the proposal that directly calling ``super(*p, **kw)`` would
|
||
be equivalent to calling the method on the ``super`` object with the same name
|
||
as the method currently being executed i.e. the following two methods would be
|
||
equivalent:
|
||
|
||
::
|
||
|
||
def f(self, *p, **kw):
|
||
super.f(*p, **kw)
|
||
|
||
::
|
||
|
||
def f(self, *p, **kw):
|
||
super(*p, **kw)
|
||
|
||
There is strong sentiment for and against this, but implementation and style
|
||
concerns are obvious. Guido has suggested that this should be excluded from
|
||
this PEP on the principle of KISS (Keep It Simple Stupid).
|
||
|
||
|
||
|
||
History
|
||
=======
|
||
12-Mar-2009 - Updated to reflect the current state of implementation.
|
||
|
||
29-Apr-2007 - Changed title from "Super As A Keyword" to "New Super"
|
||
- Updated much of the language and added a terminology section
|
||
for clarification in confusing places.
|
||
- Added reference implementation and history sections.
|
||
|
||
06-May-2007 - Updated by Tim Delaney to reflect discussions on the python-3000
|
||
and python-dev mailing lists.
|
||
|
||
References
|
||
==========
|
||
|
||
.. [1] Fixing super anyone?
|
||
(https://mail.python.org/pipermail/python-3000/2007-April/006667.html)
|
||
|
||
.. [2] PEP 3130: Access to Module/Class/Function Currently Being Defined (this)
|
||
(https://mail.python.org/pipermail/python-ideas/2007-April/000542.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:
|