This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author ncoghlan
Recipients ashwch, ncoghlan, rhettinger
Date 2017-08-20.05:14:07
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1503206049.0.0.113146350739.issue31118@psf.upfronthosting.co.za>
In-reply-to
Content
Thanks for the suggestion, but I'm closing this RFE, as there are two strong arguments against it: one related to implementation feasibility, and one related to the nature of what super() *does*.

The feasibility argument is that the compiler doesn't even have the necessary information to do this, since it doesn't know what kind of method it's dealing with (it has no idea what decorators actually do, it just compiles them as subexpressions). Instead, the compiler blindly translates "super()" into "super(__class__, <first positional argument>)" when inside a function definition that's inside a class definition. As a result, there's no way for the compiler to special case static methods and pass __class__ as the second argument as well.

Even without considering that technical limitation though, using __class__ for both arguments doesn't do anything particularly sensible, since super() is specifically about resolving name lookups using the *dynamic* method resolution order (MRO) of the class the method was retrieved from (which may be a subclass of the class defining the method).

So in instance methods and class methods, type(self) or cls provides the dynamic MRO to use, while __class__ identifies *where* along that MRO the currently running method implementation sits.

In a static method, there's no dynamic MRO available for super() to query. This means that if you want access to one, you need to convert the method to a classmethod first so that the interpreter will pass in a reference to the class the method was retrieved from (as opposed to the one where it was defined, which is what __class__ gives you).

If folks actually do want to make a method implementation in a child class depend on a static method in a parent class, there are two ways to do that, but only one of them will work correctly in the face of multiple inheritance:

1. Make the child method a class method. This is the most readable approach, since you can then use zero-argument super() to call the staticmethod in the parent class in the usual way. As long as all child classes overriding the method adhere to this approach, that particular class hierarchy will also reliably respect Python's MRO linearisation rules in the case of multiple inheritance.

2. Make the child method a staticmethod, and then use "super(__class__, __class__)" to access the staticmethod in the parent class. This will work OK in cases where there aren't any diamonds in the inheritance hierarchy, but it completely bypasses the dynamic C3 linearisation algorithm, and hence may do weird things in the presence of such diamonds (i.e. cases where a subclass has multiple inheritance paths back to a given base class - see https://python-history.blogspot.com.au/2010/06/method-resolution-order.html for more detail on this).
History
Date User Action Args
2017-08-20 05:14:09ncoghlansetrecipients: + ncoghlan, rhettinger, ashwch
2017-08-20 05:14:09ncoghlansetmessageid: <1503206049.0.0.113146350739.issue31118@psf.upfronthosting.co.za>
2017-08-20 05:14:08ncoghlanlinkissue31118 messages
2017-08-20 05:14:07ncoghlancreate