Detect async callable objects as awaitable handlers - #1858
Open
Sanjays2402 wants to merge 1 commit into
Open
Conversation
CallableObject determined awaitability with inspect.iscoroutinefunction() on the callback itself, which is False for an instance of a class whose __call__ is a coroutine function. Such handlers and filters were run via asyncio.to_thread(), so calling them returned an un-awaited coroutine and Python emitted 'coroutine was never awaited'; the handler body never ran. Awaitability now also considers type(callback).__call__, matching how Filter subclasses were already special-cased. Adds regression coverage asserting both the awaitable flag and that the call is actually awaited. Closes aiogram#1721
❌ Changelog is required!You need to add a brief description of the changes to the Changes file should be named like The content of the file should be a brief description of the changes in Possible categories are: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
CallableObject.__post_init__decided awaitability withinspect.iscoroutinefunction(callback), which isFalsefor an instance of a class whose__call__is a coroutine function. Such handlers/filters were therefore dispatched throughasyncio.to_thread(), so calling them just returned an un-awaited coroutine ("coroutine was never awaited") and the handler body never ran. Awaitability now also considerstype(callback).__call__, matching howFiltersubclasses were already special-cased.Note: the issue also mentions lambdas that return a coroutine. That is a plain sync function whose return value happens to be awaitable, which cannot be detected by introspection, so this PR intentionally only covers async callable objects.
Fixes #1721
Type of change
How Has This Been Tested?
test_call_async_callable_objectand the extendedtest_init_awaitableparametrization fail ondev-3.x(never-awaited coroutine returned) and pass with the fix.pytest tests/test_dispatcher— 133 passed, 1 skipped.Test Configuration:
Checklist: