-
Notifications
You must be signed in to change notification settings - Fork 788
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Extend the @on
decorator so that it will match superclasses
#2691
Conversation
See Textualize#2630. This is, at the moment, an experimental change. This breaks one unit test (surprisingly *only* one!), but otherwise works as intended. Next up will be investigating why that one particular test fails.
Leaning on the newer method of matching messages with @on -- this is pretty much the bit of code that inspired this in the first place.
This doesn't solve the problem I'm trying to solve, but looking at the code the following day this is neater, I think.
I don't think it makes too much of a difference.
Hold on, shouldn't the title say "[...] it will match subclasses"? |
Possibly. Depends on whose frame of reference you're you're looking from. In this case from the code that goes seeking handlers (in which case it goes looking for any superclasses that hit). From the dev's point of view: t'other way round. |
src/textual/message_pump.py
Outdated
for check_message in message.__class__.__mro__: | ||
# If we've hit something that isn't derived from Message | ||
# we can give up. | ||
if not issubclass(check_message, Message): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may fail in the case of multiple inheritance or mixins. I would hope that nobody uses those in the context of messages, but maybe we should continue rather than break.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair point, I'll add some testing for this first. The intent here was to not go further up the MRO than Message
, to save looping more than necessary (although of course, at the moment, that's only really going to save one more trip round).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test added and the "get out as soon as possible" code changed to "wander up the MRO and check anything that looks like a Message
): 02b862c
Ah, of course. |
Textualize#2691 (review) being the driving force here. Also adds a unit test for a non-message mixin into a message class hierarchy.
The test is added as a passing test, but I don't think this is the result we really want.
See Textualize#2691 (comment) The point of this change being that if the developer writes something like: @on(Some.Parent) @on(Some.Child) def some_handler(...): ... then when `Some.Child` is posted, `some_handler` only gets triggered once for that posting. Until this change it would get triggered twice because `Some.Child` matches both `Some.Parent` and `Some.Child`.
Not sure yet what the correct result here should be; based on our conversation so far it seems to be that it's working as intended; but I'm not sure it's working as intended on purpose. I think there's still a breaking test to be found and added here.
This was the breakage I was looking for.
I'm like 90% sure about this. This was a "dump it all and work from scratch" evening experiment, and I think it does what's needed, but I want to read it back over again in the morning with a post-coffee brain. Pushing to the repo so I can review then. Also added lotsa comments so tomorrow me will know what this evening me was thinking.
Be 100% sure that combined classes make a hit
Be sure that a combined set of classes with one not matching doesn't match.
Solution is good, but there were improvements on efficiency. Closing in favor of #2746 |
This PR seeks to implement the requirement laid out in #2630. In short, the idea is that the the
@on
decorator should match a given message and any message that inherits from it. To borrow from the issue this stems from, it means that this sort of hierarchy:no longer needs something like this:
but can be handles something like this:
One other small change included in this PR is to
events.Unmount
, which used to inherit fromevents.Mount
; as of this PR it inherits fromevents.Event
; just like all other events. The point of this change being that a developer van safely@on(Mount)
without needing to handle fact thatevents.Unmount
would trigger the handler too.