-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Automatic pass_* for Handlers using reflection: Autowiring #859
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
Conversation
β¦ed pass_update_queue as a positional argument.
β¦ions in handler.py
I started reading the PR and it's very clear you've put a lot of effort into it. However, that made me think that maybe we need a non-backward compat change here. I'm opening this for discussion, what about:
What do you think? |
@tsnoam This would just hand over complexity to the end user again who would be required to pick the objects from the context object (which is context sensitive in itself) and it's impossible to know what attributes are available in the type of callback you're working with which also prohibits IDE support.
Yields UserWarning: The argument In order to get the same kind of immediate error reporting with a context object, we would need to inspect the full method for its usage... and we're back at square one. As an end user I'd like my callback handlers to be somewhat explicit as to which arguments I'm using in the method, so I can see at a glance what library entities are being worked with, which serves maintainability. What autowiring does is basically just "syntactic sugar for explicitness". What you suggest is more of a Java solution than the pythonic way of doing it, and I still believe passing context sensitive arguments is superior, especially in terms of flexibility. A pro that I can see is free type hinting for the attributes of the context object. |
and for some handlers there be sub-classes providing |
I agree with @JosXa. I think it's just easier to call an argument "groups" and it magically gets assigned. The variable name makes sense and there's no need to rely on a variable "context" with more or less members. And if one doesn't like the autowiring, or prefers other parameter names, then the old mechanism would still be there. |
I'm have a bit of mixed feelings about this. I'm trying to put it in words. I think it's not bad that users know what they're doing. If they want to use the job_queue in their handler, they'll have to pass it when adding the handler. I think it makes code more readable and more obvious to understand. Adding Also, I personally know this library pretty well, that's why I know I can use shortcut methods like That said, I also agree the way it is done now is a bit archaic and might be due for an overhaul. I lean towards @tsnoam 's suggestion of a context-manager more, In the end I think it's not bad if complex things are complex to code. |
Well the way the autowiring is designed in this PR doesn't hurt new users in any way. It is just syntactic sugar that more advanced users can opt-in to leverage and keep their code short. It is not intended as a beginner-friendly feature, but it also doesn't hurt. After all, few beginners use
Special attention again to
Hmm I still don't really see how this hurts adding some ease of use for seasoned developers (only). For me personally in 6 big, active bots, it hurts like hell having to modify several places every time I need a new object from the library. A lib should support and endorse ease of use, not make it cumbersome.
To keep picking on @tsnoam's approach (sorry, please don't take it personal π), yes, it is simple. But it is in no way convenient. I don't know if you have worked on a chatbot with a huge code base, but having to prefix most (!) of the library objects with a context access is just not bearable - from a user perspective. The number of characters and complexity we save by removing the |
If naming is a problem, the flag could also be called |
@JosXa The naming is not the issue here. |
@JosXa I have thought about it long and went back and forth with my opinion. One time taking one way then taking the other.
To make a long story short, after considering it very thoroughly my personal opinion is that the autowiring approach is not the way we should go. I prefer a context object, even at the price of breaking backward compatibility. p.s. |
Going back to the case of replacing the pass_* hell with a context object. The Telethon library by @Lonami has gotten some awesome upgrades in the last couple of days and an event handling was built on top of the What do you think about naming the replacement for (bot, update) On a related note, we will obviously break backwards compatibility. But I think to build a reliable tool to convert entire user projects to the new syntax, which would presumably help a lot in the transition, aside from the mandatory deprecation period. |
The subject of "autowiring" had been discussed in the developers group several time and we've recently came to the decision that this will not be the way we go. I'm closing this PR for now. Further design discussions will take place in the developers group. |
Whenever I build bots or fix other peoples' code, I run into the problem that the
pass_something
arguments for Handlers are so explicit. Say I needchat_data
in one handler, this handler is used by other callbacks, so the other handler needschat_data
too and this process escalates to a lot of places that need adjustment. It is also quite unnecessary information to have in your routing definitions (thedispatcher.add_handler
part) since it is more a kind of implementation details than an actual targeting directive.My proposed solution to this is to do introspection on the callback so that the multitude of
pass_*
parameters is no longer required, in favor of a new parameter: autowire=True.In addition to the
pass_*
instructions,bot
andupdate
can also be used arbitrarily through this PR.This allows for a much cleaner syntax when adding handlers, please refer to the new autowiring.py example.