(Adding python-3000 to the Cc, since that is where much of the recent discussion occurred)
Calvin's full proposal is archived at: http://mail.python.org/pipermail/python-dev/2007-April/072835.html > 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) The alternatives section needs to explain why "super.foo(*args)" is the right level of simplification. Alternatives include (1) No changes Con: fragility in name binding (2) super(__this_class__, self).foo(*args) Con: The "(__this_class__, self)" is boilerplate. Note that the __this_class__ PEP should be referenced, if only as a possible explanation for what is happening under the covers. (3) self.__super__.foo(*args) # or super.foo(*args) Con: Shouldn't need a __double_underscore_name__ in normal functions. Con: __super__ (even if renamed super) is not a simple attribute; it is a property representing a partially applied function (that gets further applied by the "self") (4) super(self, *args) # ? or __super__(self, *args) Actually, I sort of like this one, as it allows the upcall signature to exactly match the method definition signature. Con: super is still not a simple attribute. Con: changing the method name becomes a hassle. (5) super.foo(self, *args) # ? or __super__.foo(self, *args) Con: self isn't really an argument just to super.foo -- it is an argument to super which is used to find/instantiate foo in the first place. (Plus the objections to partially applied function attributes.) (6) super # ? or super() Pro: matches java; doesn't require a repeat of *args Con: doesn't match anything else in python, needs to be a keyword (and would still need object support). In the first example: 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' You should probably include tests that fail with some of the more obvious (but wrong) solutions, such as class A(object): def f(self): return 'A' class Bempty(A): # Make sure it doesn't call the A or B method twice pass class B(Bempty): 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' class E(C, B): # Show that B can point to C as next or vice versa def f(self): return 'E' + super.f() assert E().f() == 'ECBA' class F(D): # show that the instance may not be a direct instance pass assert D().f() == 'DBCA' > The enhancements to the super type will define a new __getattr__ classmethod > of the super type, Did you really mean, it gets the class of builtin.super, but no info on which class is using super? If not, it isn't a classmethod of the super type. It may be a classmethod of the currently-being-defined-type (__this_class__). > which must look backwards to the previous frame and locate > the instance object. frame manipulation is fragile. Even if it didn't cause problems for other implementations, it causes problems for nested functions and callbacks. def f(self, button, *args): def callback(*args): super(__this_class__, self).f(*args) button.callback=callback When this gets called, the appropriate self won't be in the frame, except as a lexically scoped variable (which might have a different name). Also, note that this fails on most of Thomas Wouters' advanced usages. While you say that super shouldn't be called outside a method, you can't really keep the super object itself from getting returned. > "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. If you didn't say instance-specific, this would be equivalent to a class decorator, translating class A(object): ... into class A(object): ... A.__super__=super(A) As is, it gets a bit trickier, since you need to I think the translation is closer to class A(object):... @property def __super__(self): return __this_class__.__supermaker() A.__supermaker=super(A) I don't see a good non-magical way to pass both the instance and the class-at-time-of-writing (as opposed to class of calling instance), which is why the other solutions used bytecode hacks or name mangling. > Much of this was discussed in the thread of the python-dev list, "Fixing super > anyone?" [1]_. I assume you meant the python-3000 list. -jJ _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com