Nick Coghlan added the comment:

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

----------
resolution:  -> rejected
stage:  -> resolved
status: open -> closed

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue31118>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to