On 10/10/13 3:22 AM, Marco Buttu wrote:
On 10/09/2013 06:47 PM, Ned Batchelder wrote:

>>> class B(A):
...     def bfoo(*args):
...         super().afoo(*args[1:])
...
>>> B().bfoo(1, 2, 3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in bfoo
RuntimeError: super(): no arguments

How come?

The no-args super() call inspects the calling environment to determine
the class and self.  "self" is the first local name stored in
frame.f_code.co_localsplus, but *args doesn't put "args" into that entry
of the code object

But is it a bug or the behavior we want? The first (implicit) argument is stored as expected as the first one in the args tuple, and the args tuple is inserted as expected in frame.f_locals:

>>> import inspect
>>> class B(A):
...     def bfoo(*args):
...         frame = inspect.currentframe()
...         for obj, value in frame.f_locals.items():
...             print(obj, value, sep=' --> ')
...         # super().afoo(*args[1:])
...
>>> B().bfoo(1, 2, 3)
args --> (<__main__.B object at 0x7f28c960a590>, 1, 2, 3)
frame --> <frame object at 0x7f28cad4b240>

So, why does not super use it?


I haven't seen the discussion that decided the behavior of super(), but I'd guess that if you reported this as a bug, it would be closed as wontfix, because: 1) the use case you describe isn't something people actually write, 2) it would add to the complexity of super() to support it, and 3) there's a simple way to write your code that does work:

    class B(A):
        def bfoo(self, *args):
            super().afoo(*args)

(though it's a bit odd to call afoo from bfoo.)

Python has never claimed the kind of purity that makes everything work in a totally simple consistent way. super() with no args is a kind of hack to begin with. It involves a special case in the compiler (so that using the name "super" as a function call will act as if you had accessed the name "__class__" so that super can find it later), and inspecting the stack frame during execution.

It's an interesting case of the Zen of Python. It violates one ("explicit is better than implicit"), but only because of another one ("practicality beats purity"). super(MyClass, self) in Python 2 is the kind of brain-bender that so many people get wrong at first, that it's helped plenty of people to do the arguments implicitly, even if there are oddball edge cases that it doesn't seem to handle properly.

--Ned.
--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to