-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Improve various signatures that shouldn't be async def
, but currently are
#7491
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
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Cc. @sobolevn, since this partially reverts your PR 🙂 |
Would SupportsAnext need fixing? https://github.com/python/typeshed/blob/master/stdlib/_typeshed/__init__.pyi#L36 currently it requires a coroutine - but any Awaitable is supported (it gets wrapped with anext_awaitable with a default) |
Good spot. |
anext is actually slightly odd as it returns whatever
|
so the type annotation for class SupportsAnyAnext(Protocol[_T_co]):
def __anext__(self) -> _T_co: ...
class SupportsAwaitableAnext(Protcol[_T_co]):
def __anext__(self) -> Awaitable[_T_co]: ...
@overload
def anext(__i: SupportsAnyAnext[_T]) -> _T: ...
@overload
async def anext(__i: SupportsAwaitableAnext[_T], default: _VT) -> _T | _VT: ... so that anext doesn't incorrectly promote an |
Sure, but I'd imagine that if |
my point was more about preserving the return type of the _Awaitable_T_co = TypeVar("_Awaitable_T_co", bound=Awaitable, covariant=True) # bound isn't strictly true - anext supports any return value
class SupportsAnext(Protocol[_Awaitable_T_co]):
def __anext__(self) -> _Awaitable_T_co: ...
class SupportsAwaitableAnext(Protocol[_T_co]):
def __anext__(self) -> Awaitable[_T_co]: ...
_Awaitable_T = TypeVar("_Awaitable_T", bound=Awaitable)
@overload
def anext(__i: SupportsAnext[_Awaitable_T]) -> _Awaitable_T: ...
@overload
async def anext(__i: SupportsAwaitableAnext[_T], default: _VT) -> _T | _VT: ... |
It's frying my brain somewhat, but I think I understand. Thanks for the explanation! |
Co-authored-by: graingert <https//@graingert.co.uk>
2a19f1b
to
80acd91
Compare
typing.AsyncIterator
and typing.AsyncGenerator
async def
, but currently are
This comment has been minimized.
This comment has been minimized.
1 similar comment
This comment has been minimized.
This comment has been minimized.
Better now @graingert? |
async def
, but currently areasync def
, but currently are
This comment has been minimized.
This comment has been minimized.
Co-authored-by: Thomas Grainger <tagrain@gmail.com>
This comment has been minimized.
This comment has been minimized.
Thanks for the review @graingert! (I'll leave this open for a while to give other maintainers a chance to review.) |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
(Planning to merge this in a day or so, unless any other maintainers want to review, since it's sort of blocking python/mypy#12321) |
Diff from mypy_primer, showing the effect of this PR on open source code: tornado (https://github.com/tornadoweb/tornado)
- tornado/gen.py:429: error: Incompatible return value type (got "WaitIterator", expected "AsyncIterator[Any]")
- tornado/gen.py:429: note: Following member(s) of "WaitIterator" have conflicts:
- tornado/gen.py:429: note: Expected:
- tornado/gen.py:429: note: def __anext__(self) -> Coroutine[Any, Any, Any]
- tornado/gen.py:429: note: Got:
- tornado/gen.py:429: note: def __anext__(self) -> Future[Any]
boostedblob (https://github.com/hauntsaninja/boostedblob)
+ boostedblob/boost.py:547: error: Need type annotation for "task"
+ boostedblob/boost.py:547: error: Argument 1 to "create_task" has incompatible type "Awaitable[T]"; expected "Union[Generator[Any, None, <nothing>], Coroutine[Any, Any, <nothing>]]"
|
As discussed in #7475, the following methods are all "async def" functions at runtime, but should not be "async def" functions in the stub:
AsyncIterator.__anext__
AyncGenerator.__anext__
AsyncGenerator.aclose
AsyncGenerator.asend
AsyncGenerator.athrow
typing.AsyncIterator
andtyping.AsyncGenerator
represent abstract interfaces rather than concrete classes, and PEP 525, which introduced the asynchronous iteration protocol, explicitly states that it is fine for these methods to return any awaitable. The current annotations, which state that these methods have to return coroutines, are therefore too restrictive, and cause false positives.In addition to these changes:
AsyncGenerator.__anext__
is not abstract at runtime, and I don't see any reason why it should be in the stub either.AsyncGenerator.__aiter__
is also not abstract at runtime, and not even defined onAsyncGenerator
at runtime; it is simply inherited fromAsyncIterator
. I think we should do the same in the stub.AsyncGenerator.aclose
is not abstract at runtime, and I don't see any reason why it should be in the stub._typeshed.SupportsAnext.__anext__
andcontextlib._SupportsAclose.aclose
were both erroneously madeasync def
functions in Fix several methods that should beasync def
, but aren't #7107; this PR also reverts the changes that PR made to those classes.This PR reverts the changes #7105 made to
typing.pyi
, but not the changes #7105 made totypes.pyi
. I think that makes sense, as the classes intypes
are concrete classes, whereas the classes intyping
are abstract interfaces.This PR adds several entries to the allowlist, but we can take them off again if python/mypy#12343 is merged.