Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
c75c1f44
Commit
c75c1f44
authored
Nov 16, 2016
by
Yury Selivanov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue #28720: Add collections.abc.AsyncGenerator.
parent
dd246d5d
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
155 additions
and
2 deletions
+155
-2
Doc/library/collections.abc.rst
Doc/library/collections.abc.rst
+8
-0
Doc/whatsnew/3.6.rst
Doc/whatsnew/3.6.rst
+4
-0
Lib/_collections_abc.py
Lib/_collections_abc.py
+58
-1
Lib/test/test_collections.py
Lib/test/test_collections.py
+83
-1
Misc/NEWS
Misc/NEWS
+2
-0
No files found.
Doc/library/collections.abc.rst
View file @
c75c1f44
...
...
@@ -92,6 +92,7 @@ ABC Inherits from Abstract Methods Mixin
:class:`Coroutine` :class:`Awaitable` ``send``, ``throw`` ``close``
:class:`AsyncIterable` ``__aiter__``
:class:`AsyncIterator` :class:`AsyncIterable` ``__anext__`` ``__aiter__``
:class:`AsyncGenerator` :class:`AsyncIterator` ``asend``, ``athrow`` ``aclose``, ``__aiter__``, ``__anext__``
========================== ====================== ======================= ====================================================
...
...
@@ -222,6 +223,13 @@ ABC Inherits from Abstract Methods Mixin
.. versionadded:: 3.5
.. class:: Generator
ABC for asynchronous generator classes that implement the protocol
defined in :pep:`525` and :pep:`492`.
.. versionadded:: 3.6
These ABCs allow us to ask classes or instances if they provide
particular functionality, for example::
...
...
Doc/whatsnew/3.6.rst
View file @
c75c1f44
...
...
@@ -912,6 +912,10 @@ The new :class:`~collections.abc.Reversible` abstract base class represents
iterable classes that also provide the :meth:`__reversed__`.
(Contributed by Ivan Levkivskyi in :issue:`25987`.)
The new :class:`~collections.abc.AsyncGenerator` abstract base class represents
asynchronous generators.
(Contributed by Yury Selivanov in :issue:`28720`.)
The :func:`~collections.namedtuple` function now accepts an optional
keyword argument *module*, which, when specified, is used for
the ``__module__`` attribute of the returned named tuple class.
...
...
Lib/_collections_abc.py
View file @
c75c1f44
...
...
@@ -9,7 +9,8 @@ Unit tests are in test_collections.
from
abc
import
ABCMeta
,
abstractmethod
import
sys
__all__
=
[
"Awaitable"
,
"Coroutine"
,
"AsyncIterable"
,
"AsyncIterator"
,
__all__
=
[
"Awaitable"
,
"Coroutine"
,
"AsyncIterable"
,
"AsyncIterator"
,
"AsyncGenerator"
,
"Hashable"
,
"Iterable"
,
"Iterator"
,
"Generator"
,
"Reversible"
,
"Sized"
,
"Container"
,
"Callable"
,
"Collection"
,
"Set"
,
"MutableSet"
,
...
...
@@ -59,6 +60,11 @@ _coro = _coro()
coroutine
=
type
(
_coro
)
_coro
.
close
()
# Prevent ResourceWarning
del
_coro
## asynchronous generator ##
async
def
_ag
():
yield
_ag
=
_ag
()
async_generator
=
type
(
_ag
)
del
_ag
### ONE-TRICK PONIES ###
...
...
@@ -183,6 +189,57 @@ class AsyncIterator(AsyncIterable):
return
NotImplemented
class
AsyncGenerator
(
AsyncIterator
):
__slots__
=
()
async
def
__anext__
(
self
):
"""Return the next item from the asynchronous generator.
When exhausted, raise StopAsyncIteration.
"""
return
await
self
.
asend
(
None
)
@
abstractmethod
async
def
asend
(
self
,
value
):
"""Send a value into the asynchronous generator.
Return next yielded value or raise StopAsyncIteration.
"""
raise
StopAsyncIteration
@
abstractmethod
async
def
athrow
(
self
,
typ
,
val
=
None
,
tb
=
None
):
"""Raise an exception in the asynchronous generator.
Return next yielded value or raise StopAsyncIteration.
"""
if
val
is
None
:
if
tb
is
None
:
raise
typ
val
=
typ
()
if
tb
is
not
None
:
val
=
val
.
with_traceback
(
tb
)
raise
val
async
def
aclose
(
self
):
"""Raise GeneratorExit inside coroutine.
"""
try
:
await
self
.
athrow
(
GeneratorExit
)
except
(
GeneratorExit
,
StopAsyncIteration
):
pass
else
:
raise
RuntimeError
(
"asynchronous generator ignored GeneratorExit"
)
@
classmethod
def
__subclasshook__
(
cls
,
C
):
if
cls
is
AsyncGenerator
:
return
_check_methods
(
C
,
'__aiter__'
,
'__anext__'
,
'asend'
,
'athrow'
,
'aclose'
)
return
NotImplemented
AsyncGenerator
.
register
(
async_generator
)
class
Iterable
(
metaclass
=
ABCMeta
):
__slots__
=
()
...
...
Lib/test/test_collections.py
View file @
c75c1f44
...
...
@@ -19,7 +19,8 @@ from collections import namedtuple, Counter, OrderedDict, _count_elements
from
collections
import
UserDict
,
UserString
,
UserList
from
collections
import
ChainMap
from
collections
import
deque
from
collections.abc
import
Awaitable
,
Coroutine
,
AsyncIterator
,
AsyncIterable
from
collections.abc
import
Awaitable
,
Coroutine
from
collections.abc
import
AsyncIterator
,
AsyncIterable
,
AsyncGenerator
from
collections.abc
import
Hashable
,
Iterable
,
Iterator
,
Generator
,
Reversible
from
collections.abc
import
Sized
,
Container
,
Callable
,
Collection
from
collections.abc
import
Set
,
MutableSet
...
...
@@ -959,6 +960,87 @@ class TestOneTrickPonyABCs(ABCTestCase):
self
.
assertRaises
(
RuntimeError
,
IgnoreGeneratorExit
().
close
)
def
test_AsyncGenerator
(
self
):
class
NonAGen1
:
def
__aiter__
(
self
):
return
self
def
__anext__
(
self
):
return
None
def
aclose
(
self
):
pass
def
athrow
(
self
,
typ
,
val
=
None
,
tb
=
None
):
pass
class
NonAGen2
:
def
__aiter__
(
self
):
return
self
def
__anext__
(
self
):
return
None
def
aclose
(
self
):
pass
def
asend
(
self
,
value
):
return
value
class
NonAGen3
:
def
aclose
(
self
):
pass
def
asend
(
self
,
value
):
return
value
def
athrow
(
self
,
typ
,
val
=
None
,
tb
=
None
):
pass
non_samples
=
[
None
,
42
,
3.14
,
1j
,
b""
,
""
,
(),
[],
{},
set
(),
iter
(()),
iter
([]),
NonAGen1
(),
NonAGen2
(),
NonAGen3
()]
for
x
in
non_samples
:
self
.
assertNotIsInstance
(
x
,
AsyncGenerator
)
self
.
assertFalse
(
issubclass
(
type
(
x
),
AsyncGenerator
),
repr
(
type
(
x
)))
class
Gen
:
def
__aiter__
(
self
):
return
self
async
def
__anext__
(
self
):
return
None
async
def
aclose
(
self
):
pass
async
def
asend
(
self
,
value
):
return
value
async
def
athrow
(
self
,
typ
,
val
=
None
,
tb
=
None
):
pass
class
MinimalAGen
(
AsyncGenerator
):
async
def
asend
(
self
,
value
):
return
value
async
def
athrow
(
self
,
typ
,
val
=
None
,
tb
=
None
):
await
super
().
athrow
(
typ
,
val
,
tb
)
async
def
gen
():
yield
1
samples
=
[
gen
(),
Gen
(),
MinimalAGen
()]
for
x
in
samples
:
self
.
assertIsInstance
(
x
,
AsyncIterator
)
self
.
assertIsInstance
(
x
,
AsyncGenerator
)
self
.
assertTrue
(
issubclass
(
type
(
x
),
AsyncGenerator
),
repr
(
type
(
x
)))
self
.
validate_abstract_methods
(
AsyncGenerator
,
'asend'
,
'athrow'
)
def
run_async
(
coro
):
result
=
None
while
True
:
try
:
coro
.
send
(
None
)
except
StopIteration
as
ex
:
result
=
ex
.
args
[
0
]
if
ex
.
args
else
None
break
return
result
# mixin tests
mgen
=
MinimalAGen
()
self
.
assertIs
(
mgen
,
mgen
.
__aiter__
())
self
.
assertIs
(
run_async
(
mgen
.
asend
(
None
)),
run_async
(
mgen
.
__anext__
()))
self
.
assertEqual
(
2
,
run_async
(
mgen
.
asend
(
2
)))
self
.
assertIsNone
(
run_async
(
mgen
.
aclose
()))
with
self
.
assertRaises
(
ValueError
):
run_async
(
mgen
.
athrow
(
ValueError
))
class
FailOnClose
(
AsyncGenerator
):
async
def
asend
(
self
,
value
):
return
value
async
def
athrow
(
self
,
*
args
):
raise
ValueError
with
self
.
assertRaises
(
ValueError
):
run_async
(
FailOnClose
().
aclose
())
class
IgnoreGeneratorExit
(
AsyncGenerator
):
async
def
asend
(
self
,
value
):
return
value
async
def
athrow
(
self
,
*
args
):
pass
with
self
.
assertRaises
(
RuntimeError
):
run_async
(
IgnoreGeneratorExit
().
aclose
())
def
test_Sized
(
self
):
non_samples
=
[
None
,
42
,
3.14
,
1j
,
_test_gen
(),
...
...
Misc/NEWS
View file @
c75c1f44
...
...
@@ -69,6 +69,8 @@ Library
- Issue #28704: Fix create_unix_server to support Path-like objects
(PEP 519).
- Issue #28720: Add collections.abc.AsyncGenerator.
Documentation
-------------
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment