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/