diff options
author | Guido van Rossum <guido@dropbox.com> | 2015-12-03 17:32:05 -0800 |
---|---|---|
committer | Guido van Rossum <guido@dropbox.com> | 2015-12-03 17:32:05 -0800 |
commit | ce2650fda4a76943394ed78942eadb07623d63cd (patch) | |
tree | c091df68aebc350bd4c459e41453abe6e933958c | |
parent | 3ab6c981e7e10a23f4efa82a4bd26e4b7d5775c4 (diff) | |
parent | f17c20076cb9e6b96cf1f1fe19062b397ff58b3a (diff) | |
download | cpython-git-ce2650fda4a76943394ed78942eadb07623d63cd.tar.gz |
Add Awaitable, AsyncIterable, AsyncIterator to typing.py. (Merge 3.5->3.6)
-rw-r--r-- | Lib/test/test_typing.py | 61 | ||||
-rw-r--r-- | Lib/typing.py | 15 |
2 files changed, 76 insertions, 0 deletions
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 060119a134..b9ca64259f 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -1,3 +1,4 @@ +import asyncio import pickle import re import sys @@ -960,6 +961,36 @@ class OverloadTests(TestCase): pass +T_a = TypeVar('T') + + +class AwaitableWrapper(typing.Awaitable[T_a]): + + def __init__(self, value): + self.value = value + + def __await__(self) -> typing.Iterator[T_a]: + yield + return self.value + + +class AsyncIteratorWrapper(typing.AsyncIterator[T_a]): + + def __init__(self, value: typing.Iterable[T_a]): + self.value = value + + def __aiter__(self) -> typing.AsyncIterator[T_a]: + return self + + @asyncio.coroutine + def __anext__(self) -> T_a: + data = yield from self.value + if data: + return data + else: + raise StopAsyncIteration + + class CollectionsAbcTests(TestCase): def test_hashable(self): @@ -984,6 +1015,36 @@ class CollectionsAbcTests(TestCase): assert isinstance(it, typing.Iterator[int]) assert not isinstance(42, typing.Iterator) + def test_awaitable(self): + async def foo() -> typing.Awaitable[int]: + return await AwaitableWrapper(42) + g = foo() + assert issubclass(type(g), typing.Awaitable[int]) + assert isinstance(g, typing.Awaitable) + assert not isinstance(foo, typing.Awaitable) + assert issubclass(typing.Awaitable[Manager], + typing.Awaitable[Employee]) + assert not issubclass(typing.Awaitable[Employee], + typing.Awaitable[Manager]) + g.send(None) # Run foo() till completion, to avoid warning. + + def test_async_iterable(self): + base_it = range(10) # type: Iterator[int] + it = AsyncIteratorWrapper(base_it) + assert isinstance(it, typing.AsyncIterable) + assert isinstance(it, typing.AsyncIterable) + assert issubclass(typing.AsyncIterable[Manager], + typing.AsyncIterable[Employee]) + assert not isinstance(42, typing.AsyncIterable) + + def test_async_iterator(self): + base_it = range(10) # type: Iterator[int] + it = AsyncIteratorWrapper(base_it) + assert isinstance(it, typing.AsyncIterator) + assert issubclass(typing.AsyncIterator[Manager], + typing.AsyncIterator[Employee]) + assert not isinstance(42, typing.AsyncIterator) + def test_sized(self): assert isinstance([], typing.Sized) assert not isinstance(42, typing.Sized) diff --git a/Lib/typing.py b/Lib/typing.py index 1757f13822..823f9be5d8 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -28,6 +28,9 @@ __all__ = [ # ABCs (from collections.abc). 'AbstractSet', # collections.abc.Set. + 'Awaitable', + 'AsyncIterator', + 'AsyncIterable', 'ByteString', 'Container', 'Hashable', @@ -1261,6 +1264,18 @@ class _Protocol(metaclass=_ProtocolMeta): Hashable = collections_abc.Hashable # Not generic. +class Awaitable(Generic[T_co], extra=collections_abc.Awaitable): + __slots__ = () + + +class AsyncIterable(Generic[T_co], extra=collections_abc.AsyncIterable): + __slots__ = () + + +class AsyncIterator(AsyncIterable[T_co], extra=collections_abc.AsyncIterator): + __slots__ = () + + class Iterable(Generic[T_co], extra=collections_abc.Iterable): __slots__ = () |