If you want to explicitly delegate a method to a class, you should
explicitly delegate a method to a class.

This is exactly why a lot of folks feel composition is better than
inheritance (at least often so).

You don't need `super()` to call `SomeSpecificClass.method(self, other,
args)`

On Sat, Mar 26, 2022, 12:59 PM malmiteria <martin.mi...@ensc.fr> wrote:

> Hi,
>
> Before anything, i made a github repository about this topic here :
> https://github.com/malmiteria/super-alternative-to-super
>
> The core of what i wanna discuss here is that i don't think mro and super
> (mainly because it relies on mro) are very pythonic. Mainly that some
> behaviors of the mro are too implicit, and are silencing what really should
> be errors.
>
>
>
> Let me explain :
> in case of multiple inheritence, resolving a child method from it's parent
> isn't an obvious task, and mro comes as a solution to that. However, i
> don't understand why we don't let the programmer solve it. I think this is
> similar to a merge conflict, and not letting the programmer resolve the
> conflict feels like silencing an error. This is especially infuriating when
> you realise that mro doesn't solve all possible scenarios, and then, simply
> refuses the opportunity to solve it to the programmer.
> Then, super relying on mro gives off some weird behaviors, mainly, it's
> possible for a child definition to affect what a call to super means in
> it's parent. This feels like a side effect (which is the 'too implicit'
> thing i refer to).
> I also don't understand why we can't simply pass the parent targeted as
> argument to super, instead of having no argument, or having to pass the
> current class and instances as argument :
> super(child) is a proxy to parent, when super(parent) would make more
> sense to be the proxy to parent, in my mind.
>
> I dive in more depths about those topics in the readme of the github
> repository i linked at the top of this comment.
>
>
>
> what i propose is a solution that would follow those rules:
>
> The mro alternative, which i called explicit method resolution aka EMR
> (which is probably not a good name since i apply it, as mro, to all class
> attributes), follow those rules :
>  1) Straightforward case : the class definition has the method / attribute
> : this is the one EMR should resolve to
>  2) Not found : the method / attribute can't be resolved in the class
> itself, or by any of it's parents, then it should raise an AttributeError
>  3) Only on parent : the method / attribute can't be resolved in the class
> itself, and can only be resolved by one of it's parents, this is the one
> EMR should resolve to
>  4) Multiple parent : the method / attribute can't be resolved in the
> class itself, and can be resolved by at least 2 of it's parents, then an
> ExplicitResolutionRequired error should be raised
>  5) Transimittin errors : the method / attribute can't be resolved in the
> class itself, and one parent at least raises an ExplicitResolutionRequired
> error, then it should raise an ExplicitResolutionRequired error
>  6) (optional?) Single source : when multiple parent can resolve a method
> from a single source (in case of diamond shape inheritence), the
> ExplicitResolutionRequired  is not needed
>
> The super alternative, which i called __as_parent__ should follow those
> rules :
>  1) reliability : the target __as_parent__ points to should not depend on
> anything other than the argument passed to it
>  2) expliciteness : in case of multiple inheritence, the parent targetted
> should be passed as an argument to the __as_parent__ method.
>  3) impliciteness : in case of simple inheritence, it is not needed to
> specify the parent targeted (since there can only be one, and it make it
> closer to the actual behavior of super in most cases)
>  4) ancestors as targets : should be able to target ancestors, either
> direct or not (which is needed in case two grandparent define a method that
> a single parent share, there would be no other way to solve the
> ExplicitResolutionRequired otherwise)
>
>
>
> this solution has a few advantages in my mind :
>  - the current mro and super are more tightly coupled than the emr and
> __as_parent__ i propose here
>  - the __as_parent__ is more reliable than super in its behavior, and
> should lead to an easier learning curve
>  - the emr i propose as a replacement to mro allows for some inheritence
> tree mro doesn't allow.
>  - the __as_parent__ method being able to target specific parent allows
> for different methods to visit the parents in different order easily, which
> today would be harder, since the parent visiting order is tightly coupled
> to the class definition
>  - with emr, in case of problematic resolution, an error is raised to tell
> you about the problem, and ask you for explicit resolution, the current
> solution doesn't, which can lead to surprises closer to production
> environment.
>
>
>
> A few possible downsides :
>  - the transition would be a pain to deal with
>  - the current mro allows for dependencies injection in the inheritence
> tree. I believe this feature should be untied from super and mro, but it
> would require some work.
>  - the current super and mro are old enough to have been faced with issues
> and having been updated to solve those issues down the line. Any
> alternative would have to face those issues again and new ones down the line
>  - any coexistence between those two solution would require some work to
> make sure they don't break one another (i've explored some of those
> scenarios in my repository, but i definitely didn't cover it all)
>
>
> I believe that what i talk about here is definitely too much at once.
> For exemple, adding a kwarg to super to specify the parent it targets
> would be a very easy change to add into python, and wouldn't require much
> more of what i talk about here, but it would still have some of the value i
> talk about here.
> But overall, it all makes sense to me, and i wanted to share it all with
> you guys.
>
> What do you think? does it makes sense? Am i missing something?
> _______________________________________________
> 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/RWAJY7TJETZEWYQJUZURLNMYSEV2TCDL/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
_______________________________________________
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/CT25LJHON5BBMVMUG7TCGRGBMPNX5LHO/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to