[Python-checkins] r55063 - peps/trunk/pep-0000.txt peps/trunk/pep-3133.txt

guido.van.rossum python-checkins at python.org
Wed May 2 00:06:35 CEST 2007


Author: guido.van.rossum
Date: Wed May  2 00:06:34 2007
New Revision: 55063

Added:
   peps/trunk/pep-3133.txt   (contents, props changed)
Modified:
   peps/trunk/pep-0000.txt
Log:
Add PEP 3133: New Super (Spealman).
Remove outdated pepparade link.


Modified: peps/trunk/pep-0000.txt
==============================================================================
--- peps/trunk/pep-0000.txt	(original)
+++ peps/trunk/pep-0000.txt	Wed May  2 00:06:34 2007
@@ -17,10 +17,6 @@
     once assigned are never changed.  The SVN history[1] of the PEP
     texts represent their historical record.
 
-    The BDFL maintains his own Pronouncements page[2] at
-    http://www.python.org/doc/essays/pepparade.html which contains his
-    musings on the various outstanding PEPs.
-
 
 Index by Category
 
@@ -132,6 +128,7 @@
  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)
@@ -506,6 +503,7 @@
  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
 
 
@@ -635,10 +633,6 @@
     [1] View PEP history online
         http://svn.python.org/projects/peps/trunk/
 
-    [2] The Benevolent Dictator For Life's Parade of PEPs
-        http://www.python.org/doc/essays/pepparade.html
-
-
 
 Local Variables:
 mode: indented-text

Added: peps/trunk/pep-3133.txt
==============================================================================
--- (empty file)
+++ peps/trunk/pep-3133.txt	Wed May  2 00:06:34 2007
@@ -0,0 +1,254 @@
+PEP: 3133
+Title: New Super
+Version: $Revision$
+Last-Modified: $Date$
+Author: Calvin Spealman <ironfroggy at gmail.com>
+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:


More information about the Python-checkins mailing list