diff --git a/pep-0000.txt b/pep-0000.txt index 57c4981a4..963b48d60 100644 --- a/pep-0000.txt +++ b/pep-0000.txt @@ -128,7 +128,6 @@ Index by Category S 3130 Access to Current Module/Class/Function Jewett S 3131 Supporting Non-ASCII Identifiers von Löwis S 3132 Extended Iterable Unpacking Brandl - S 3133 New Super Spealman S 3141 A Type Hierarchy for Numbers Yasskin Finished PEPs (done, implemented in Subversion) @@ -503,7 +502,6 @@ Numerical Index S 3130 Access to Current Module/Class/Function Jewett S 3131 Supporting Non-ASCII Identifiers von Löwis S 3132 Extended Iterable Unpacking Brandl - S 3133 New Super Spealman S 3141 A Type Hierarchy for Numbers Yasskin diff --git a/pep-3133.txt b/pep-3133.txt deleted file mode 100644 index 17f025787..000000000 --- a/pep-3133.txt +++ /dev/null @@ -1,254 +0,0 @@ -PEP: 3133 -Title: New Super -Version: $Revision$ -Last-Modified: $Date$ -Author: Calvin Spealman -Status: Draft -Type: Standards Track -Content-Type: text/x-rst -Created: 28-Apr-2007 -Python-Version: 2.6 -Post-History: 28-Apr-2007, 29-Apr-2007 - - -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 -============= - -Within the specification section, some special terminology will be used to -distinguish similar and closely related concepts. "Super type" will refer to -the actual builtin type named "super". "Next Class/Type in the MRO" will refer -to the class where attribute lookups will be performed by super, for example, -in the following, A is the "Next class in the MRO" for the use of super. - - :: - - class A(object): - def f(self): - return 'A' - - class B(A): - def f(self): - super(B, self).f() # Here, A would be out "Next class in the - # MRO", of course. - -A "super object" is simply an instance of the super type, which is associated -with a class and possibly with an instance of that class. Finally, "new super" -refers to the new super type, which will replace the original. - -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. - - :: - - 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 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. - -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. This special method will actually be invoked on attribute lookups to -the super type itself, as opposed to super objects, as the current -implementation works. This may pose open issues, which are detailed below. - -"Every class will gain a new special attribute, __super__, which refers to an -instance of the associated super object for that class" In this capacity, the -new super also acts as its own descriptor, create an instance-specific super -upon lookup. - -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. - -Actually keeping the old super around in 2.x and creating a completely new super -type seperately may be the best option. A future import or even a simple import -in 2.x of the new super type from some builtin module may offer a way to choose -which each module uses, even mixing uses by binding to different names. Such a -builtin module might be called 'newsuper'. This module is also the reference -implementation, which I will present below. - -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. - - -Reference Implementation -======================== - -This implementation was a cooperative contribution in the original thread [1]_. - - :: - - #!/usr/bin/env python - # - # newsuper.py - - import sys - - class SuperMetaclass(type): - def __getattr__(cls, attr): - calling_frame = sys._getframe().f_back - instance_name = calling_frame.f_code.co_varnames[0] - instance = calling_frame.f_locals[instance_name] - return getattr(instance.__super__, attr) - - class Super(object): - __metaclass__ = SuperMetaclass - def __init__(self, type, obj=None): - if isinstance(obj, Super): - obj = obj.__obj__ - self.__type__ = type - self.__obj__ = obj - def __get__(self, obj, cls=None): - if obj is None: - raise Exception('only supports instances') - else: - return Super(self.__type__, obj) - def __getattr__(self, attr): - mro = iter(self.__obj__.__class__.__mro__) - for cls in mro: - if cls is self.__type__: - break - for cls in mro: - if attr in cls.__dict__: - x = cls.__dict__[attr] - if hasattr(x, '__get__'): - x = x.__get__(self, cls) - return x - raise AttributeError, attr - - class autosuper(type): - def __init__(cls, name, bases, clsdict): - cls.__super__ = Super(cls) - - if __name__ == '__main__': - class A(object): - __metaclass__ = autosuper - 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, arg=None): - var = None - return 'D' + Super.f() - - assert D().f() == 'DBCA' - - -History -======= -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. - -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: