<br><div><span class="gmail_quote">On 4/19/06, <b class="gmail_sendername">Guido van Rossum</b> &lt;<a href="mailto:guido@python.org">guido@python.org</a>&gt; wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>&gt; &gt;Oh, I believe super() also supports static and/or class methods. I'm<br>&gt; &gt;not sure how to handle this but I'm sure you can think of something.<br>&gt;<br>&gt; If super.foobar(args) -&gt; super(ThisClass,firstarg).foobar(args), then it
<br>&gt; will Just Work(TM) for class methods, since their first argument is the<br>&gt; class, and super(someclass,myclass).aClassMethod(...) is the normal way of<br>&gt; invoking a superclass classmethod.<br><br>But how about static methods? Inside a static method, I believe you're
<br>allowed to write<br><br>&nbsp;&nbsp;super(ThisClass).foobar(args)<br><br>which would call<br><br>&nbsp;&nbsp;ThisClass.__base__.foobar(args)<br><br>(assuming single inheritance for a moment) i.e. nothing is added to<br>the argument list.
</blockquote><div><br>That's not how it works (and that's good; refusing the temptation to guess, and what not :) super() cannot make any assumptions about the next class in the MRO, and since you don't *have* a class in a staticmethod, it has no way to find out. staticmethods just can't sensibly call 'their baseclass method' (unless they're really just &quot;explicit classmethods&quot;, like __new__, but those best be real classmethods (even __new__ :))
<br><br>Currently, super(ThisClass) returns an 'unbound super object', which is not a proxy for 'the next class' but rather an descriptor that would get the right proxy object upon retrieval:<br><br>&gt;&gt;&gt; class X(object):
<br>...&nbsp;&nbsp;&nbsp; @staticmethod<br>...&nbsp;&nbsp;&nbsp; def static(*args):<br>...&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print &quot;X.static%r&quot; % (args,)<br>... <br>&gt;&gt;&gt; class Y(X):<br>...&nbsp;&nbsp;&nbsp; @staticmethod<br>...&nbsp;&nbsp;&nbsp; def static(*args):<br>...&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print &quot;
Y.static%r&quot; % (args,)<br>...&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super(Y).static(*args) <br>... <br>&gt;&gt;&gt; Y.static()<br>Y.static()<br>Traceback (most recent call last):<br>&nbsp; File &quot;&lt;stdin&gt;&quot;, line 1, in ?<br>&nbsp; File &quot;&lt;stdin&gt;&quot;, line 5, in static
<br>AttributeError: 'super' object has no attribute 'static'<br>&gt;&gt;&gt; y = Y()<br>&gt;&gt;&gt; y.static()<br>Y.static()<br>Traceback (most recent call last):<br>&nbsp; File &quot;&lt;stdin&gt;&quot;, line 1, in ?<br>&nbsp; File &quot;&lt;stdin&gt;&quot;, line 5, in static
<br>AttributeError: 'super' object has no attribute 'static'<br><br>And to prove it's a descriptor:<br>&gt;&gt;&gt; class Z(X):<br>...&nbsp;&nbsp;&nbsp;&nbsp; @staticmethod<br>...&nbsp;&nbsp;&nbsp;&nbsp; def static(*args):<br>...&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print &quot;Z.static%r&quot; % (args,)
<br>...&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super(Z).__get__(Z, None).static(*args)<br>... <br>&gt;&gt;&gt; Z.static()<br>Z.static()<br>X.static()<br>&gt;&gt;&gt; Z().static()<br>Z.static()<br>X.static()<br><br>Doing super(Z).__get__(Z, None).static is just as static as calling 
X.static, though (with the only difference being that you name Z multiple times, instead of naming X multiple times.) It doesn't take MI into account at all.<br></div><br>And yes, staticmethods are damned near useless. Let's not worry about them calling their baseclass methods -- they honestly shouldn't.
<br></div><br>-- <br>Thomas Wouters &lt;<a href="mailto:thomas@python.org">thomas@python.org</a>&gt;<br><br>Hi! I'm a .signature virus! copy me into your .signature file to help me spread!