On Tue, 29 Mar 2022 at 07:39, malmiteria <martin.mi...@ensc.fr> wrote:
>
> Chris Angelico writes:
> > I'm not sure what you DO expect, though.
>
> in this case :
> ```
> class A:
>   def method(self): pass
>
> class B:
>   def method(self): pass
>
> class C(A,B): pass
> ```
>
> it is unclear what C().method should resolve to. So instead of forcing a 
> resolution, i'd prefer an error to be raised, stating that the resolution 
> can't be done automatically. Hence the name ExplicitResolutionRequired.
>
> This is what i would expect from calling C().method in this example.
> Or at least, this is how my solution would behave.

Please, can we get a non-toy example? I look at this example and go
"of course it should resolve to A.method", but that's because, with
these names, there is absolutely no clue as to your intention. The
only thing I have to go on is the code itself, and to my mind, there
are two equally plausible options: either the first one named takes
precedence, or both methods should be called. Python chose one of
those options. Other languages have chosen the other. But with nothing
to go on but the code, all I can say is: the current behaviour looks
perfectly fine to me.

> > Which of these super() calls would, by your description, need to raise
> > an error?
>
> None, actually.
> super should not raise the ExplicitResolutionRequired error, never.
> Accessing a method from a child class, which don't redefine it, when multiple 
> parent have it, should raise the error.

Sure, but whatever. Whether it's the super call itself or the
attribute lookup on the super object, which ones need to raise?

And once again, you're just giving us toy examples with names that
tell us nothing. Please, real examples. Show us how this is actually
useful.

> Updating C's code like that :
> ```
> class C(A,B):
>   def method(self):
>     self.__as_parent__(A).method() # calls method defined in A
>     self.__as_parent__(B).method() # calls method defined in B
> ```
>
> now running ```C().method``` works fine.

The trouble is, if I now create these:

class D(B): pass
class E(C, D): pass

then C's methods should be delegating to D and not to B. That's a
fundamental problem for any sort of explicit lookup.

Also, how is this different from simply writing:

class C(A, B):
    def method(self):
        A.method(self)
        B.method(self)

? If you're going to explicitly call for a particular parent, why not
just do that?

> Note that with the use of super, you can't tell in the body of the C method 
> how to combine A and B's methods.
> You have to rely on super order of visiting those methods.
> Meaning that in this specific example you'd need either to add a call to 
> super in A, for it to call B's method, or a call to super(A, self) in C for 
> it to call B's method, without having to change A's definition.

Yes. That's intentional. Usually, that is a deliberate and desired feature.

> > It's far less obvious than you perhaps think, so please elaborate,
> > please show exactly what constitutes an error.
> I apologise if i wasn't clear, i hope it's better now.
> I'll do my best to explicit my idea more in the future too.
>

Unfortunately, no, it's not. With names like A, B, and C, we have to
figure out our own purpose behind things, and I've spent so much time
with Python's existing system that everything seems fine to me. You'll
need to show exactly what doesn't work with the current system,
instead of assuming that we understand the problem. Real example.

> > "class C(B1, A, B2)", you could have some parts of what's currently in
> > B happen before A, and other parts happen after A.
>
> You can't always break a class down, especially when you import those class 
> from a library.

Again, real example please.

> The fact that the current super + MRO make it the norm to simply chop off the 
> behavior of class B's method parent call to replace it by C's method behavior 
> is literraly insane to me.
>
> In what world extending a parent method means replacing part of it with some 
> of another parent?

Well....... generally, since Python doesn't allow you to call two
functions at the same time, the *only* way to extend a parent method
is to replace *all* of it. To replace part of it, you replace all of
it and then call the other function, That's precisely what
super().method() lets you do. So.... what you call "literally insane",
I call "a perfectly normal feature". Hence, again, the need to see
what you're actually trying to accomplish - not "replace the MRO", but
what you're really trying to do with your code. Take a step back and
show us your actual goals, because we cannot see the problems the way
you see them.

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/JEDKPES2MJ4HO6Z3XIRKYNA3QBF22J7L/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to