On Sat, Apr 16, 2022 at 05:27:57PM +1200, Greg Ewing wrote:
> On 15/04/22 10:37 pm, Steven D'Aprano wrote:
> >If you look at languages that implement MI, and pick the implementations 
> >which allow it with the fewest restrictions, then that is "full MI".
> 
> >I believe that Python (and other languages) allow MI with
> >the smallest set of restrictions, namely that there is a C3
> >linearization possible
> 
> But before Python adopted the C3 algorithm, it was less
> restrictive about the inheritance graph.

Less restrictive, and *inconsistent* (hence buggy).


> So by your definition, current Python does not do full MI!

No, I'm excluding inconsistent models of MI.

Correctness is a hard requirement. Otherwise we get into the ludicrous 
territory of insisting that every feature can be implemented with one 
function:

    def omnipotent_function(*args, **kwargs):
        """Function which does EVERYTHING.

        (Possibly not correctly, but who cares?)
        """
        return None

There you go, now we can define an MRO for any class hierarchy 
imaginable, and dispatch to the next class in that hierarchy, using the 
same function. It won't work, of course, but if correctness isn't a hard 
requirement, what does that matter? :-)


> >If you have to manually call a specific method, as shown here:
> >
> >https://devblogs.microsoft.com/oldnewthing/20210813-05/?p=105554
> >
> >you're no longer using inheritance, you're doing delegation.
> 
> You could also say that Python automatically delegates to the first
> method found by searching the MRO.
> 
> Why is one of these delegation and not the other?

That is a very interesting question.

As I mentioned earlier, there is a sense that all inheritance is a kind 
of delegation, and in languages without an explicit super() (or 
"nextclass", or whatever you want to call it), the only way to get 
inheritance when you overload a method is to use explicit delegation to 
your superclass.

So we might say that all inheritance is delegation, but not all 
delegation is inheritance. We might even go further and say that any 
delegation to a superclass (not just the direct parent) is a form of 
manual inheritance.

But in general, in ordinary language, when we talk about inheritance, 
we're talking about two (maybe three) cases:

1. Automatic inheritance, when your class doesn't define a method but 
   automatically inherits it from its superclass(es).

    class Parent:
        def method(self): pass

    class Child(Parent):
        pass

    assert hasattr(Child, "method")


2. Automatic inheritance when your class overloads a method and calls
   super() manually to delegate to the superclass(es).

    class Child(Parent):
        def method(self):
            print("Overload")
            super().method()

3. And more dubiously, but commonly used, when people who don't like 
   super(), or know about it, explicitly delegate to their  
   parent in single inheritance:

    class Child(Parent):
        def method(self):
            print("Overload")
            Parent.method(self)  # Oooh, flashbacks to Python 1.5



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

Reply via email to