Paul Moore writes:

> I
> personally think this is probably useless, but it's not a Python
> change so do it if you want.

I agree, this is most likely useless. Other people on this thread were worried 
about dependency injection through MRO injection being lost by my proposal, 
today's __bases__ attribute edits are enough to cover those cases.
This is in essence my answer to this worry.

taking about adoption proposal :
> I have no idea what the point of this is. And you've made no attempt
> to describe use cases that would gain from this

I've described it multiple times in the past few days.
You've explicitely stated you didn't read my previous posts, but i've desribed 
it in recent posts too.

I'll dedicate its own thread to this proposal, as i believe it brings value to 
python on its own, perhaps we can disscuss this proposal in more depth there.

about the diamond problem:
> You've not defined this at all, nor have you explained why it's
> needed.
again, i have, you chose not to read it, don't hold that against me lol.

the problem is about class inheritance trees in which a class appears multiple 
times.
Today's MRO enforces uniqueness of visits, but some use case like the gobelin 
exemple would benefit from an alternative option.

a keyword argument to super would allow for it:
```
super(<possible class and instance argument, >use_target_mro=True)
```
would allow for super to transit to the class it proxie's MRO in call to super 
made in this class.
This ensures the behavior of this class to be exactly the same when called from 
direct instances, or from calls to super.

My gobelin exemple would look like that:
```
class HighGobelin:
    def scream(self):
        print("raAaaaAar")

class CorruptedGobelin(HighGobelin):
    def scream(self):
        print("my corrupted soul makes me wanna scream")
        super().scream()

class ProudGobelin(HighGobelin):
    def scream(self):
        print("I ... can't ... contain my scream!")
        super().scream()

class HalfBreed(ProudGobelin, CorruptedGobelin):
    def scream(self):
        if random.choice([True, False]):
            super(HalfBreed, self, use_target_mro=True)
            # could be just super(use_target_mro=True)
        else:
            super(ProudGobelin, self, use_target_mro=True)
```


about super targeting argument:
> This is a breaking change (passing an argument to super means
> something different right now).

The updated proposal is not a breaking change

to reuse the exemple above, this is what i would get:

```
class HalfBreed(ProudGobelin, CorruptedGobelin):
    def scream(self):
        if random.choice([True, False]):
            super(target=ProudGobelin, instance=self, use_target_mro=True)
            # could be just super(use_target_mro=True)
        else:
            super(target=CorruptedGobelin, instance=self, use_target_mro=True)
```

super() is still allowed and would behave the exact same.
super(cls, self) is still allowed and would behave the exact same.
If you think this is a breaking change, please provide me with an exemple this 
feature would break.
As it comes on top of existing feature, but does not replace any, i very much 
doubt it even *can* be a breaking change.


about MRO:
> super is not the only way the MRO is used. And you can't just "remove"
> it anyways
poor choice of words on my part, i meant replaced.

> "removing" any resolution order makes no sense.
but removing the ordering of parents does.


> So making the programmer do all the work, rather than having a default
> behaviour that works in at least some cases. That's strictly worse
> than the current behaviour.
most cases would be resolved the exact same.
cases with ML, and only for attribute presents in both parent, would behave 
differently.
There is no single solution that covers all merge needs.
Requesting a solution from the developper in those cases is a benefit, as much 
as requesting developpers to perform git merge manually only in case of 
conflict is beneficial, depsite git ability to perform git merge automatically 
in most cases.
You're entitled to your opinion of course, and so am i.
I believe i made a fair case that today's solution doesn't fit all needs, let's 
own up to that, instead of pretending we do.

> So this is essentially making some existing functionality raise an
> error, without any new functionality.
raising an error *is* the functionality.
in this case :
```
class A:
    value = 'a'
class B:
    value = 'b'
class C(B,A):
    pass
```
C.value equals 'a', B.value is refused inheritance.
Assuming you import classes A and B from library you don't own, you have no 
idea what their attributes are.
Whenever you create a class that inherits from multiple imported classes, you 
have that "sword of Damocles" hanging over you, that you might discover only 
after encountering the side effects of such name collision.

My solution raises an error here.
And in no other cases btw.
This would lead you to realise as soon as you're accessing this attribute, that 
there actually is a conflict, and a potential side effect problem.
I already hear you ask, then how do you solve it?
Good question.
The exact same way you'd be solving it today.
Minus the horrible debugging because nothing was pointing you out to this name 
collision.

There is no design today that i'm aware of that provide a solution for this 
problem.
I know you can make attribute somewhat privates, by prefixing them with __ if i 
remember correctly, but this is only a solution for the parent class author, 
not the child class author.


> Demonstrating relevant
> real-world use cases that would be improved by your proposed changes
> is another part.
Which use case have i presented to you, that you believe my proposal would make 
worse than today's solution, even just a little, and which use case have i 
presented to you, that you believe bring some value?
I'm aware you think raising an error for the method resolution in case of 
conflict is a downside, i've adressed it, feel free to counter that point too.

the point i think my proposal improves are essentially easier debugging for 
some ML scenarios (collision of names case), wider range for super use cases, 
more ways to control supers behavior in case of ML, removing MRO's limitation 
that is allowing only some class inheritance trees today.

Do you disagree with any of those, and why?
Do you think there's other use case that i didn't cover, that would eventually 
reduce some of todays features that i didn't account for?
please if you do, provide use cases.
_______________________________________________
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/66ZYBAQIQ3EKPIHVJXRDOLIFH6O5W52Z/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to