On Tue, 5 Apr 2022 at 03:58, malmiteria <martin.mi...@ensc.fr> wrote:
>
> Steven D'Aprano writes:
> > > feature 1 (of super alone): proxying the parent.
> > > What most people think super does (and expect it to do):
> > > it allows to call method from *the* (most people don't think of
> > > multiple inheritance) parent.
> > For single inheritance, that is exactly what it does, and there is no
> > problem. Just use super() and it Just Works.
>
> I 100% agree.
> I don't see a problem with super and MRO for today's single inheritance.
>
> That's why I explicitely care to make my porposal equivalent to today's super 
> and MRO in single inheritance scenarios.
>
> > > It can be used by working around MRO to proxy any parent directly.
> > I don't know what you mean by this. Why are you "working around" the
> > MRO?
>
> super(A, self) does not proxy to A, but to the first *after* A in MRO order.
> When you're actually in need to passing arguments to super, you very likely 
> know what class you're gonna be targeting, and having to run MRO logic in 
> reverse to call super to the class that comes first before your target in MRO 
> order is what i refer to as "working around MRO".
>

This right here, this is the fundamental problem.

When you call super(A, self), you are expecting to call A's method.
This is simply wrong. This is not super's job.

If you want to call A's method, call A.method(self). Don't call super.

If you want to call the next method after A, use super(A, self). And
most of the time, what you want is "the next method after this class",
which is super(__class__, self), and can be abbreviated super().

You are working around super because you assume that every call must
go through it. That's simply not the case. You are working around
*your own misunderstanding of super*, and then blaming super for your
awkwardness.

*STOP USING SUPER* where it's the wrong tool for the job. Your
problems will vanish.

> > Again, this sounds like inheritance is the wrong tool here. Nnot
> > everything is an inheritance relationship.
> Nnot the only one making typos hehe :p

I never ask people to avoid making any typos... but I do ask people to
test *code blocks* before posting them.

(And, yes, I have been guilty of posting untested and buggy code
blocks. But you'd be fully justified in calling me out on that one.)

> > > feature 4 (of MRO alone): method resolution
> > This is the one and only thing that super() if for. Well to be precise,
> > its not just methods, but any attributes.
> super does not provide method resolution.
> MRO gives the order in which attribute / method would be looked up for.
>
> ```
> class A:
>     def method(self): pass
> class B(A): pass
>
> B().method() # works despite B body not declaring "method", and resolves to 
> the method defined in A body.
> ```
> This is method resolution. super is not a part of it
> Although, super do rely on it, since it will target the next in MRO order to 
> select the class to proxy.

They're closely linked. The MRO exists, and super is used as a means
of skipping part of it.

> > The diamond problem is a feature of multiple inheritance with diamonds.
> > super() can't solve it in the fully general case because there is no
> > general solution.
> That's why my proposal includes a inheritence strategy module, which would 
> allows users to pick and choose which kind of strategy they need.
> It would default to the current strategy which consists of calling the parent 
> that apppears multiple times in an inheritance tree only on its last 
> occurence.
> Other strategy could be to call parent that appear multiple times on each 
> occurence, or even to specify which occurence should be called, and which 
> should be ignored.
> That's a "no general solution" problem solved.

Python *already has* all these strategies. Some of them involve the
use of super. Some do not.

> > is to try (and fail!) to use inheritance for behaviour which needs to be
> > modelled by delegation.
> > [...]
> > And you provide the right solution: delegation.
> Today's right solution.
> Again, i'm showcasing a limit of today's super.

Is super the wrong tool for the job? Don't use super.

Python's integer type has some fairly severe limitations, notably that
it can't handle fractional values. Let's change the int type to be
more intuitive - dividing an int by an int should return an int, with
the exact value of that fraction. So 17/3 should return an int with
the value of five and two thirds. That's intuitive, right? Today's int
type has this weird limit.

Or maybe I should be using Fraction or float instead of int. Maybe
that's a better solution.

> > By definition, inheritance requires HalfBreed to call the methods of all
> > three superclasses. (That is at least the definition used in Python,
> > other languages may do differently.) If HalfBreed is not using the
> > methods of all its superclasses, it is not really an inheritance
> > relationship.
> By this definition, the behavior i wanna implement in HalfBreed is one of 
> inheritance, as it is using the methods of all its superclasses.
> As you were quick to point out, super does not cover this scenario, which is 
> the problem i'm highlighting with this example.

Is it a problem that super doesn't handle this (somewhat weird and
extremely hypothetical) situation? You can use explicit method
resolution instead.

ChrisA
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/SJVGMOKWUFAYNH7WFMP5KSB2YYPLHDGG/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to