Skip to content
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

A class with async "__call__" method fails to work as a middleware #1131

Closed
chet-manley opened this issue Aug 20, 2024 · 1 comment · Fixed by #1132
Closed

A class with async "__call__" method fails to work as a middleware #1131

chet-manley opened this issue Aug 20, 2024 · 1 comment · Fixed by #1132
Assignees
Labels
area:async bug Something isn't working
Milestone

Comments

@chet-manley
Copy link

(Filling out the following details about bugs will help us solve your issue sooner.)

Reproducible in:

pip freeze | grep slack
python --version
sw_vers && uname -v # or `ver`

The slack_bolt version

slack-bolt==1.18.1
slack_sdk==3.31.0

Python runtime version

Python 3.11.9

OS info

bash: sw_vers: command not found
❯ uname -a
Linux 49d1cffcb728 6.8.4-200.fc39.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Apr  4 20:45:21 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux

Steps to reproduce:

(Share the commands to run, source code, and project settings (e.g., setup.py))

from slack_bolt.app.async_app import AsyncApp

class MyCallableMiddleware:

    async def __call__(self, next_) -> None:
        await next_()

app = AsyncApp()
app.middleware(MyCallableMiddleware()) # this raises `ValueError: Async middleware function must be an async function`

Expected result:

AsyncApp.middleware accepts any Callable[..., Awaitable[Any]] object, per signature.

Actual result:

The middleware instance pass the callable check here
https://github.com/slackapi/bolt-python/blob/main/slack_bolt/app/async_app.py#L678
and is thus sent to AsyncCustomMiddleware init here
https://github.com/slackapi/bolt-python/blob/main/slack_bolt/middleware/async_custom_middleware.py#L13
where the signature for func is Callable[..., Awaitable[Any]] (which my middleware instance is).
However, inspect.iscoroutinefunction is used to check func, which does not pass, as it checks for the existence of
CO_COROUTINE flag (see here: CPython source),
despite the instance being both callable and asynchronous.

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.

@seratch seratch added bug Something isn't working area:async labels Aug 21, 2024
@seratch seratch added this to the 1.21.0 milestone Aug 21, 2024
@seratch seratch changed the title AsyncCustomMiddleware iscoroutinefunction check breaks func: Callable signature A class with async "__call__" method fails to work as a middleware Aug 21, 2024
@seratch seratch self-assigned this Aug 21, 2024
@seratch
Copy link
Member

seratch commented Aug 21, 2024

Hi @chet-manley, thanks for reporting this issue. The built-in inspect library's behaviuor is a bit surprising, but it seems this scenario should be supported. I found a workaround on bolt-python side, so will come up with a pull request resolving it. Once it's merged, we will release a new patch release fixing the issue.

seratch added a commit to seratch/bolt-python that referenced this issue Aug 21, 2024
seratch added a commit to seratch/bolt-python that referenced this issue Aug 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:async bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants