Steven D'Aprano, 27.05.2011 18:06:
On Fri, 27 May 2011 08:31:40 -0700, sturlamolden wrote:

On 27 Mai, 17:05, Duncan Booth<duncan.bo...@invalid.invalid>  wrote:

Oops. There's a reason why Python 2 requires you to be explicit about
the class; you simply cannot work it out automatically at run time.
Python 3 fixes this by working it out at compile time, but for Python 2
there is no way around it.

Then it should be a keyword, not a function.

Why?

I think Sturla is referring to the "compile time" bit. CPython cannot know that the builtin super() will be called at runtime, even if it sees a "super()" function call.

CPython doesn't evaluate the super call at compile time, it only keeps a reference to the surrounding class in the code object of the method. So super() without arguments basically inherits the class argument from the context the method was found in at compile time. This has two quirks:

1) Copying a method from one class to another keeps the original context. So the class argument to super() is basically fixed at compile time, regardless of the class the method will be executed on at runtime.

2) The class is only kept as a reference when CPython sees a function call that looks like "super" at compile time, which isn't much more than a heuristic.

The PEP doesn't mention the first issue, but it is actually explicit about the second issue:

http://www.python.org/dev/peps/pep-3135/

"""
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.
"""

And the prove:

  >>> _super = super
  >>> class T(object):
  ...   def test(self): print('TEST')
 ...
  >>> class B(T):
  ...   def meth(self): _super().test()
  ...
  >>> B().meth()
  Traceback (most recent call last):
  SystemError: super(): __class__ cell not found

I assume this is done in order to reduce the chance of accidentally keeping a class object alive for eternity, only because a method was originally defined therein that inherits the class reference in its code object. So it's a tradeoff between memory overhead and usability issues.

While I think that the tradeoff is generally ok, I agree with Sturla that a keyword would have been the correct solution, whereas this is a clear "works only in the common cases" approach.

Stefan

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to