-
-
Notifications
You must be signed in to change notification settings - Fork 2k
Tweak pre-3.8 iscoroutine stub #8104
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
Tweak pre-3.8 iscoroutine stub #8104
Conversation
This comment has been minimized.
This comment has been minimized.
|
I don't think we should do this. |
|
There is a real usability issue here though. I wouldn't mind lying here and having |
6b1eed2 to
9eff23b
Compare
This comment has been minimized.
This comment has been minimized.
|
Hi, I updated the PR with the |
stdlib/asyncio/coroutines.pyi
Outdated
| def iscoroutine(obj: object) -> TypeGuard[types.GeneratorType[Any, Any, Any] | Coroutine[Any, Any, Any]]: ... | ||
| def iscoroutine( | ||
| obj: object, | ||
| ) -> Annotated[TypeGuard[Coroutine[Any, Any, Any]], "can actually be a generator-style coroutine"]: ... |
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.
I'd prefer to have a comment instead of using Annotated here, in the off-chance this interacts poorly with someone else's use of Annotated.
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.
Happy with that too.
|
According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉 |
AlexWaygood
left a comment
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.
Sounds like we're all happy with this now. Thanks for the PR!
Refs #6105 (comment)
This PR updates the stub for
asyncio.iscoroutine(coro).#6105 chose to define the return type as
Union[GeneratorType, Coroutine]on Python pre-3.8. The rationale was that generator-style coroutine functions (@asyncio.coroutine()) were deprecated in Python 3.8, so developers running in previous versions of Python (Python 3.7 is the only non-EOL example) needed to know that what they get might not be an actualCoroutine.asyncio does have
GeneratorTypeas a possible_COROUTINE_TYPE:So at runtime,
asyncio.iscoroutine(coro)isTrueifcorocomes from an@asyncio.coroutine(), i.e. functions decorated like this do returnGeneratorTypeinstances.But type checkers don't seem to be aware of this. In fact, at check time,
corois shown as anAwaitableGenerator, not aGenerator. ThisAwaitableGeneratoris a special type defined in typeshed specifically for this use case:typeshed/stdlib/typing.pyi
Lines 392 to 396 in 1be5918
(It is marked for displacement from
typingto_typeshed, here: #7580. I'm using the current location here.)By using
GeneratorTypein the stub, #6105 made it impossible to use the type guard before anawait coroon Python pre-3.8 (i.e. 3.7), because mypy raises an error saying that generators can't be awaited.To reproduce, run
mypy --python-version 3.7on this script:mypy output:
This PR switches to
AwaitableGeneratorwhich seems to be the proper check-time type.I originally stumbled upon this in: encode/httpx#2269