python/peps
| 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, 29-Apr-2007 (1), 29-Apr-2007 (2), 14-May-2007, 12-Mar-2009 | |
| 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 | |
| invokation 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: |