Misc asyncio changes (#373)

* Add stub for cgi.parse_header().

* Improve asyncio stubs (far from complete)

* More asyncio changes.

* Use @overload to solve strange test failures.

* Add some TODOs. Make ProactorEventLoop conditional.

* Future should not inherit from Awaitable or implement __await__.

At least not yet.

* Fix AbstractServer.wait_closed() return type.

It's a generator, not a future.
This commit is contained in:
Guido van Rossum
2016-07-15 15:44:29 -07:00
committed by Matthias Kramm
parent 6aeea2a872
commit 6d8628c247
7 changed files with 117 additions and 24 deletions

View File

@@ -1,4 +1,8 @@
"""The asyncio package, tracking PEP 3156."""
import sys
from typing import Type
from asyncio.coroutines import (
coroutine as coroutine,
iscoroutinefunction as iscoroutinefunction,
@@ -48,7 +52,13 @@ from asyncio.events import (
AbstractEventLoop as AbstractEventLoop,
AbstractServer as AbstractServer,
Handle as Handle,
get_event_loop_policy as get_event_loop_policy,
set_event_loop_policy as set_event_loop_policy,
get_event_loop as get_event_loop,
set_event_loop as set_event_loop,
new_event_loop as new_event_loop,
get_child_watcher as get_child_watcher,
set_child_watcher as set_child_watcher,
)
from asyncio.queues import (
Queue as Queue,
@@ -58,5 +68,22 @@ from asyncio.queues import (
QueueFull as QueueFull,
QueueEmpty as QueueEmpty,
)
from asyncio.locks import (
Lock as Lock,
Event as Event,
Condition as Condition,
Semaphore as Semaphore,
BoundedSemaphore as BoundedSemaphore,
)
# TODO: It should be possible to instantiate these classes, but mypy
# currently disallows this.
# See https://github.com/python/mypy/issues/1843
SelectorEventLoop = ... # type: Type[AbstractEventLoop]
if sys.platform == 'win32':
ProactorEventLoop = ... # type: Type[AbstractEventLoop] # TODO: Windows only
DefaultEventLoopPolicy = ... # type: Type[AbstractEventLoopPolicy]
# TODO: AbstractChildWatcher (UNIX only)
__all__ = ... # type: str

View File

@@ -1,9 +1,9 @@
from typing import Callable, Any, TypeVar
from typing import Any, Callable, Generator, TypeVar
__all__ = ... # type: str
_T = TypeVar('_T')
_F = TypeVar('_F', bound=Callable[..., Any])
def coroutine(func: _T) -> _T: ...
def coroutine(func: _F) -> _F: ...
def iscoroutinefunction(func: Callable[..., Any]) -> bool: ...
def iscoroutine(obj: Any) -> bool: ...

View File

@@ -25,7 +25,7 @@ class Handle:
class AbstractServer:
def close(self) -> None: ...
@coroutine
def wait_closed(self) -> None: ...
def wait_closed(self) -> Generator[Any, Any, None]: ...
class AbstractEventLoop(metaclass=ABCMeta):
@abstractmethod
@@ -58,9 +58,9 @@ class AbstractEventLoop(metaclass=ABCMeta):
# Network I/O methods returning Futures.
@abstractmethod
def getaddrinfo(self, host: str, port: int, *,
family: int = ..., type: int = ..., proto: int = ..., flags: int = ...) -> List[Tuple[int, int, int, str, tuple]]: ...
family: int = ..., type: int = ..., proto: int = ..., flags: int = ...) -> Future[List[Tuple[int, int, int, str, tuple]]]: ...
@abstractmethod
def getnameinfo(self, sockaddr: tuple, flags: int = ...) -> Tuple[str, int]: ...
def getnameinfo(self, sockaddr: tuple, flags: int = ...) -> Future[Tuple[str, int]]: ...
@abstractmethod
def create_connection(self, protocol_factory: Any, host: str = ..., port: int = ..., *,
ssl: Any = ..., family: int = ..., proto: int = ..., flags: int = ..., sock: Any = ...,
@@ -152,18 +152,25 @@ class AbstractEventLoopPolicy(metaclass=ABCMeta):
@abstractmethod
def set_event_loop(self, loop: AbstractEventLoop): ...
@abstractmethod
def new_event_loop(self) -> Any: ... # return selector_events.BaseSelectorEventLoop
def new_event_loop(self) -> AbstractEventLoop: ...
# Child processes handling (Unix only).
@abstractmethod
def get_child_watcher(self) -> Any: ... # return unix_events.AbstractChildWatcher
def get_child_watcher(self) -> Any: ... # TODO: unix_events.AbstractChildWatcher
@abstractmethod
def set_child_watcher(self, watcher: Any) -> None: ... # gen unix_events.AbstractChildWatcher
def set_child_watcher(self, watcher: Any) -> None: ... # TODO: unix_events.AbstractChildWatcher
class BaseDefaultEventLoopPolicy(AbstractEventLoopPolicy):
def __init__(self) -> None: ...
def get_event_loop(self) -> AbstractEventLoop: ...
def set_event_loop(self, loop: AbstractEventLoop): ...
def new_event_loop(self) -> Any: ... # Same return than AbstractEventLoop
def new_event_loop(self) -> AbstractEventLoop: ...
def get_event_loop_policy() -> AbstractEventLoopPolicy: ...
def set_event_loop_policy(policy: AbstractEventLoopPolicy) -> None: ...
def get_event_loop() -> AbstractEventLoop: ...
def set_event_loop(loop: AbstractEventLoop) -> None: ...
def new_event_loop() -> AbstractEventLoop: ...
def get_child_watcher() -> Any: ... # TODO: unix_events.AbstractChildWatcher
def set_child_watcher(watcher: Any) -> None: ... # TODO: unix_events.AbstractChildWatcher

View File

@@ -0,0 +1,59 @@
from typing import Any, Callable, Generator, Iterable, Iterator, TypeVar, Union
from .coroutines import coroutine
from .events import AbstractEventLoop
from .futures import Future
T = TypeVar('T')
__all__ = ... # type: str
class _ContextManager:
def __init__(self, lock: Union[Lock, Semaphore]) -> None: ...
def __enter__(self) -> object: ...
def __exit__(self, *args: Any) -> None: ...
class _ContextManagerMixin(Future[_ContextManager]):
# Apparently this exists to *prohibit* use as a context manager.
def __enter__(self) -> object: ...
def __exit__(self, *args: Any) -> None: ...
def __aenter__(self): ...
def __aexit__(self, exc_type, exc, tb): ...
class Lock(_ContextManagerMixin):
def __init__(self, *, loop: AbstractEventLoop = None) -> None: ...
def locked(self) -> bool: ...
@coroutine
def acquire(self) -> Future[bool]: ...
def release(self) -> None: ...
class Event:
def __init__(self, *, loop: AbstractEventLoop = None) -> None: ...
def is_set(self) -> bool: ...
def set(self) -> None: ...
def clear(self) -> None: ...
def wait(self) -> bool: ...
class Condition(_ContextManagerMixin):
def __init__(self, lock: Lock = None, *, loop: AbstractEventLoop = None) -> None: ...
def locked(self) -> bool: ...
@coroutine
def acquire(self) -> Future[bool]: ...
def release(self) -> None: ...
@coroutine
def wait(self) -> Future[bool]: ...
@coroutine
def wait_for(self, predicate: Callable[[], T]) -> Future[T]: ...
def notify(self, n: int = 1) -> None: ...
def notify_all(self) -> None: ...
class Semaphore(_ContextManagerMixin):
def __init__(self, value: int = 1, *, loop: AbstractEventLoop = None) -> None: ...
def locked(self) -> bool: ...
@coroutine
def acquire(self) -> Future[bool]: ...
def release(self) -> None: ...
class BoundedSemaphore(Semaphore):
def __init__(self, value=1, *, loop: AbstractEventLoop = None) -> None: ...

View File

@@ -11,7 +11,7 @@ class BaseProtocol:
def resume_writing(self) -> None: ...
class Protocol(BaseProtocol):
def data_received(self, data: AnyStr) -> None: ...
def data_received(self, data: bytes) -> None: ...
def eof_received(self) -> bool: ...
class DatagramProtocol(BaseProtocol):

View File

@@ -1,4 +1,4 @@
from typing import Iterable, Tuple, Callable, Any, AnyStr
from typing import Any, Callable, Generator, Iterable, Tuple
ClientConnectedCallback = Callable[[Tuple[StreamReader, StreamWriter]], None]
import socket
@@ -23,7 +23,7 @@ def open_connection(
*,
loop: events.AbstractEventLoop = ...,
limit: int = ...,
**kwds: Any) -> Tuple[StreamReader, StreamWriter]: ...
**kwds: Any) -> Generator[Any, None, Tuple[StreamReader, StreamWriter]]: ...
@coroutines.coroutine
def start_server(
@@ -62,7 +62,7 @@ class StreamReaderProtocol(FlowControlMixin, protocols.Protocol):
loop: events.AbstractEventLoop = ...) -> None: ...
def connection_made(self, transport: transports.BaseTransport) -> None: ...
def connection_lost(self, exc: Exception) -> None: ...
def data_received(self, data: AnyStr) -> None: ...
def data_received(self, data: bytes) -> None: ...
def eof_received(self) -> bool: ...
class StreamWriter:
@@ -73,12 +73,12 @@ class StreamWriter:
loop: events.AbstractEventLoop) -> None: ...
@property
def transport(self) -> transports.BaseTransport: ...
def write(self, data: AnyStr) -> None: ...
def writelines(self, data: Iterable[str]) -> None: ...
def write(self, data: bytes) -> None: ...
def writelines(self, data: Iterable[bytes]) -> None: ...
def write_eof(self) -> None: ...
def can_write_eof(self) -> bool: ...
def close(self) -> None: ...
def get_extra_info(self, name: Any, default: Any = ...) -> Any: ...
def get_extra_info(self, name: str, default: Any = ...) -> Any: ...
def drain(self) -> None: ...
class StreamReader:
@@ -90,12 +90,12 @@ class StreamReader:
def set_transport(self, transport: transports.BaseTransport) -> None: ...
def feed_eof(self) -> None: ...
def at_eof(self) -> bool: ...
def feed_data(self, data: AnyStr): ...
def feed_data(self, data: bytes): ...
@coroutines.coroutine
def readline(self) -> str: ...
def readline(self) -> Generator[Any, None, bytes]: ...
@coroutines.coroutine
def readuntil(self, separator=b'\n') -> str: ...
def readuntil(self, separator=b'\n') -> Generator[Any, None, bytes]: ...
@coroutines.coroutine
def read(self, n=-1) -> str: ...
def read(self, n=-1) -> Generator[Any, None, bytes]: ...
@coroutines.coroutine
def readexactly(self, n) -> str: ...
def readexactly(self, n) -> Generator[Any, None, bytes]: ...

View File

@@ -1,4 +1,4 @@
from typing import Any, Iterable, TypeVar, Set, Dict, List, TextIO, Union, Tuple, Generic, Callable, Generator
from typing import Any, TypeVar, Set, Dict, List, TextIO, Union, Tuple, Generic, Callable, Generator, Iterable, Awaitable
__all__ = ... # type: str
@@ -22,7 +22,7 @@ class Task(Future[_T], Generic[_T]):
def current_task(cls, loop: AbstractEventLoop = ...) -> Task: ...
@classmethod
def all_tasks(cls, loop: AbstractEventLoop = ...) -> Set[Task]: ...
def __init__(self, coro: Union[Future[_T], Generator[Any, None, _T]], *, loop: AbstractEventLoop = ...) -> None: ...
def __init__(self, coro: Union[Awaitable[_T], Iterable[_T], Future[_T], Generator[Any, None, _T]], *, loop: AbstractEventLoop = ...) -> None: ...
def __repr__(self) -> str: ...
def get_stack(self, *, limit: int = ...) -> List[Any]: ... # return List[stackframe]
def print_stack(self, *, limit: int = ..., file: TextIO = ...) -> None: ...