> wait, what?

> We may need some more clarity as to what you are after. You need SOME
> method resolution order, and Python's MRO is pretty simple and straight
> froward.

You don't need a method resolution *order*, you just need method resolution.
That's essentially the punchline.

It makes sense that a child is more specific than its parents.
It doesn't make sense that any parent would be more specific than any others 
(at the same depth at least).

That's what my alternative does, i've coded it already, you can take a look at 
it : https://github.com/malmiteria/super-alternative-to-super
I've tested it thoroughly, so you can also take a look at the tests to figure 
out how it behaves.

But essentially, I do *not* order parents. I let conflict raise an error when 
they need to (and only when they need to).
Then of course, solving the issue requires to define the method in the child, 
and eventually say which parent's method it should refer to, or in which order 
visit both, depending on cases.

Since super relies on MRO, and i produced an alternative to MRO, i have to 
produce an alternative to super.
And since my alternative to MRO doesn't order the inheritance tree, my 
alternative to super can't rely on that order.
so essentially i can do it like that :
```
class A:
  def A_first(self):
    # calls super
  def B_first(self):
    # calls super

class B:
  def A_first(self):
    # calls super
  def B_first(self):
    # calls super

class C(A,B):
  def A_first(self):
    # calls super
  def B_first(self):
    # calls super
```

becomes

```
class A:
  def A_first(self):
    # doesn't call super
  def B_first(self):
    # doesn't call super

class B:
  def A_first(self):
    # doesn't call super
  def B_first(self):
    # doesn't call super

class C(A,B):
  def A_first(self):
    self.__as_parent__(A).A_first()
    self.__as_parent__(B).A_first()
  def B_first(self):
    self.__as_parent__(B).A_first()
    self.__as_parent__(A).A_first()
```

You'll notice that no parents need specific code to be used in multiple 
inheritance.
Todays alternative with class.method, there are cases where you couldn't make 
it work like you want.
Especially if on of the classes calls super and not that class.method 
alternative, it could lead to part of the methods being called in a loop.



Now, why do i want this change? let's take a comparison:
today's MRO feels like saying that git merge isn't needed, since we can order 
changes priority in the code.
It makes sense to say one change should be applied if only one branch does it.
It doesn't make sense to apply one of the changes first, by asusming we can 
order branches in any ways.

There is a conflict, and no clear rules exists, resolution depends on context. 
Anyone telling you that you can just apply changes in order would seem crazy to 
you, and it would seem obvious to you that the current solution, which relies 
on letting the programmer solve the conflict manually when it araise is much 
safer.

That's my point here. Conflicting names of method existing in both parents 
should really be considered a conflict, and require manual solving, as i 
illustrated it above.
The alternative i produced (again, feel free to take a look at my repository) 
does not require so much work, in case of a conflict, and is behaving almost 
identically to current MRO + super in simple cases where implicitness is 
definitely enough.



------


> But the author of C should certainly test that, and choose what order to
> put them in. It's possible they would want one method from A, and one from
> B, but then they could override those methods if they need to.

Yes, my solution does only raise error when needed, with the explicit purpose 
to give that information to the developper : They need to override the method 
in the child and choose the order.
Current day MRO + super doesn't allow for you to decide this order. And doesn't 
raise any error, which can lead to unexpected behaviors.
Essentially, my proposal is to just stop assuming we can solve this problem in 
a generic way. We can't, but we can identify it, and raise an error when it 
happens, to request the developper explicit solution.



----


> I don’t think that’s even possible.

> Even a tiny modicum of testing would take care of that.

Yeah, today it's not possible. super is bound to inheritance trees, 
class.method isn't which means you can accidentally get 'out of bound' of the 
inheritance tree when using class.method.
My alternative keeps it bound to inheritance trees, and raises appropriate 
errors when you're getting out of bound.
It's only to make life easier when writing code.
It makes the programmers life easier, just a tiny modicum. But that's still an 
improvment.


---


> Steven A mentioned the two seminal articles “super considered harmful” and
> “super considered helpful” — the thing is, they both say the same thing— in
> order for super() to work you have to follow certain rules. And then it
> works predictably. Whether that’s helpful or not depends on your use case.

I'm familiar with part of those seminal, but they seem to miss something. 
Ordering is not the solution to multiple inheritance method resolution.
My alternative doesn't require you to follow certain rules, not as much as 
current super + MRO does, which makes the langage easier to learn and use.
_______________________________________________
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/UDMOMUZSOD5N26IGIUYVVKTDRQBUZRT5/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to