-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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. 🤖🎉 |
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
GeneratorType
as a possible_COROUTINE_TYPE
:So at runtime,
asyncio.iscoroutine(coro)
isTrue
ifcoro
comes from an@asyncio.coroutine()
, i.e. functions decorated like this do returnGeneratorType
instances.But type checkers don't seem to be aware of this. In fact, at check time,
coro
is shown as anAwaitableGenerator
, not aGenerator
. ThisAwaitableGenerator
is 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
typing
to_typeshed
, here: #7580. I'm using the current location here.)By using
GeneratorType
in the stub, #6105 made it impossible to use the type guard before anawait coro
on 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.7
on this script:mypy output:
This PR switches to
AwaitableGenerator
which seems to be the proper check-time type.I originally stumbled upon this in: encode/httpx#2269