-
Notifications
You must be signed in to change notification settings - Fork 250
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
kwarg injection does not work with decorated functions #688
Comments
Hi @deppe, thanks for reporting this! We will resolve this issue shortly (I'm already working on the PR for it). |
Hi @seratch, I'm implementing a custom decorator to authorize each user based on the team they belong to within our organization. The idea is to easily add a filter onto any event listener. In the below pseudo example, if the user that said "hi" isn't on team1 or team2, the bot won't respond with "hello" but will instead respond with a message saying the user doesn't have access to that keyword/feature, which is implemented in the
I was able to get this working but I'd like to abstract away a little more code in the custom Is there a way around this to where I can always access |
Since Bolt's design philosophy requires your listener functions to have all the necessary arguments in the method signature, I don't think this is feasible. Instead of implementing your own decorator, I would suggest using listener middleware / matchers. You can receive any arguments in the function and you can reuse it for any listeners: https://slack.dev/bolt-python/concepts#listener-middleware |
Hi @seratch, Apologies for commenting on an old, and closed, issue, but I didn't want to open an entire new one, considering my question related directly to your comment - has there been any consideration in the time since regarding custom decorators that abstract logic away from the listeners? Changing the get_arg_names_of_callable to: def get_arg_names_of_callable(func: Callable) -> List[str]:
# Check if the func is decorated and if the decorator requires specific data injection
# in the case of a decorator that handles *args and **kwargs, the length of inspect.getfullargspec(func).args is 0,
# so we can defer to the unwrapped func
if hasattr(func, '__wrapped__') and inspect.getfullargspec(func).args:
return inspect.getfullargspec(func).args
return inspect.getfullargspec(inspect.unwrap(func)).args would retain the original fix made with #689 but also allow the function to inject arguments required by the decorator, instead of the listener function. I do, however, also realize this comes with a lot of assumptions and downsides (user has to handle arguments modifications, passing parameters properly to the listener, and a whole other can of worms) which might not be something you want to maintain in the long run. |
@dimitarOnGithub Thanks for the suggestion. Indeed, your suggestion may be helpful for some scenarios. If you're happy to contribute to this project using your time, a pull request with sufficient unit test code that demonstrates the scenarios to cover by its change would be greatly appreciated! If we need to discuss a bit more details before making code changes, please feel free to write in here or create a new issue for it. |
Reproducible in:
The
slack_bolt
versionPython runtime version
OS info
Steps to reproduce:
*args, **kwargs
. Example:Expected result:
say
andbody
should be properly injected into thehandle_mentions
listenerActual result:
This throws the following error:
TypeError: handle_mentions() missing 2 required positional arguments: 'say' and 'body'
Potential fix:
The slack bolt code currently uses inspect to get args like
arg_names = inspect.getfullargspec(func).args
. Instead, it could unwrap the func first:inspect.getfullargspec(inspect.unwrap(func)).args
.Requirements
Please read the Contributing guidelines and Code of Conduct before creating this issue or pull request. By submitting, you are agreeing to those rules.
The text was updated successfully, but these errors were encountered: