[Python-3000] [Python-Dev] PEP 367: New Super
Guido van Rossum
guido at python.org
Sun May 27 11:59:45 CEST 2007
On 5/26/07, Tim Delaney <timothy.c.delaney at gmail.com> wrote:
> Guido van Rossum wrote:
> > Quick, since I'm about to hop on a plane: Thinking about it again,
> > storing the super instance in the bound method object is fine, as long
> > as you only do it when the bound function needs it. Using an unbound
> > super object in an unbound method is also fine.
>
> OTOH, I've got a counter argument to storing the super object - we don't
> want to create a permantent cycle.
The bound method object isn't stored in the class -- it's created by
the "C.method" or "inst.method" getattr operation. I don't see how
this would introduce a cycle.
> If we store the class, we can store it as a weakref - the when the super
> object is created, a strong reference to the class exists.
>
> We can't store a weakref to the super instance though, as there won't be any
> other reference to it.
>
> I still quite like the idea of im_super though, but it would need to be a
> property instead of just a reference.
>
> I also agree with Jim that exposing the class object is useful e.g. for
> introspection.
>
> So I propose the following:
>
> 1. Internal weakref to class object.
>
> 2. im_type - property that returns a strong ref to the class object.
>
> I went through several names before coming up with im_type (im_staticclass,
> im_classobj, im_classobject, im_boundclass, im_bindingclass). I think
> im_type conveys exactly what we want this attribute to represent - the
> class/type that this method was defined in.
>
> im_class would have also been suitable, but has had another, different
> meaning since 2.2.
Since class and type are synonym (as you say) having both im_class and
in_type would be a bad idea.
> 3. im_super - property that returns the unbound super object (for an unbound
> method) and bound super object (for a bound method).
>
> Tim Delaney
>
> > On 5/26/07, Tim Delaney <timothy.c.delaney at gmail.com> wrote:
> >> Guido van Rossum wrote:
> >>
> >>>>> - Why not make super a keyword, instead of just prohibiting
> >>>>> assignment to it? (I'm planning to do the same with None BTW in
> >>>>> Py3k -- I find the "it's a name but you can't assign to it" a
> >>>>> rather silly business and hardly "the simplest solution".)
> >>>>
> >>>> That's currently an open issue - I'm happy to make it a keyword -
> >>>> in which case I think the title should be changed to "super as a
> >>>> keyword" or something like that.
> >>>
> >>> As it was before. :-)
> >>>
> >>> What's the argument against?
> >>
> >> I don't see any really, especially if None is to become a true
> >> keyword. But some people have raised objections.
> >>
> >>>> Th preamble will only be added to functions/methods that cause the
> >>>> 'super' cell to exist i.e. for CPython have 'super' in co.cellvars.
> >>>> Functions that just have 'super' in co.freevars wouldn't have the
> >>>> preamble.
> >>>
> >>> I think it's still too vague. For example:
> >>>
> >>> class C:
> >>> def f(s):
> >>> return 1
> >>> class D(C):
> >>> pass
> >>> def f(s):
> >>> return 2*super.f()
> >>> D.f = f
> >>> print(D().f())
> >>>
> >>> Should that work? I would be okay if it didn't, and if the super
> >>> keyword is only allowed inside a method that is lexically inside a
> >>> class. Then the second definition of f() should be a (phase 2)
> >>> SyntaxError.
> >>
> >> That would simplify things. I'll update the PEP.
> >>
> >>> Was it ever decided whether the implicitly bound class should be:
> >>>
> >>> - the class object as produced by the class statement (before
> >>> applying class decorators);
> >>> - whatever is returned by the last class decorator (if any); or
> >>> - whatever is bound to the class name at the time the method is
> >>> invoked?
> >>> I've got a hunch that #1 might be more solid; #3 seems asking for
> >>> trouble.
> >>
> >> I think #3 is definitely the wrong thing to do, but there have been
> >> arguments put forwards for both #1 and #2.
> >>
> >> I think I'll put it as an open issue for now.
> >>
> >>> There's also the issue of what to do when the method itself is
> >>> decorated (the compiler can't know what the decorators mean, even
> >>> for built-in decorators like classmethod).
> >>
> >> I think that may be a different issue. If you do something like:
> >>
> >> class A:
> >> @decorator
> >> def func(self):
> >> pass
> >>
> >> class B(A):
> >> @decorator
> >> def func(self):
> >> super.func()
> >>
> >> then `super.func()` will call whatever `super(B, self).func()` would
> >> now, which (I think) would result in calling the decorated function.
> >>
> >> However, I think the staticmethod decorator would need to be able to
> >> modify the class instance that's held by the method. Or see my
> >> proposal below ...
> >>> We could make the class in question a fourth attribute of the
> >>> (poorly named) "bound method" object, e.g. im_class_for_super
> >>> (im_super would be confusing IMO). Since this is used both by
> >>> instance methods and by the @classmethod decorator, it's just about
> >>> perfect for this purpose. (I would almost propose to reuse im_self
> >>> for this purpose, but that's probably asking for subtle backwards
> >>> incompatibilities and not worth it.)
> >>
> >> I'm actually thinking instead that an unbound method should
> >> reference an unbound super instance for the appropriate class -
> >> which we could then call im_super.
> >>
> >> For a bound instance or class method, im_super would return the
> >> appropriate bound super instance. In practice, it would work like
> >> your autosuper recipe using __super.
> >>
> >> e.g.
> >>
> >> class A:
> >> def func(self):
> >> pass
> >>
> >>>>> print A.func.im_super
> >> <super: <class 'A'>, NULL>
> >>
> >>>>> print A().func.im_super
> >> <super: <class 'A'>, <A object>>
> >>
> >>> See my proposal above. It differs slightly in that the __super__
> >>> call is made only when the class is not NULL. On the expectation
> >>> that a typical function that references super uses it exactly once
> >>> per call (that would be by far the most common case I expect) this
> >>> is just fine. In my proposal the 'super' variable contains whatever
> >>> __super__(<class>, <inst>) returned, rather than <class> which you
> >>> seem to be proposing here.
> >>
> >> Think I must have been explaining poorly - if you look at the
> >> reference implementation in the PEP, you'll see that that's exactly
> >> what's held in the 'super' free variable.
> >>
> >> I think your proposal is basically what I was trying to convey -
> >> I'll look at rewording the PEP so it's less ambiguous. But I'd like
> >> your thoughts on the above proposal to keep a reference to the
> >> actual super object rather than the class.
> >>
> >> Cheers,
> >>
> >> Tim Delaney
>
>
--
--Guido van Rossum (home page: http://www.python.org/~guido/)
More information about the Python-3000
mailing list