cpython: a7a9c8631d0e (original) (raw)
Mercurial > cpython
changeset 96349:a7a9c8631d0e
Issue 24315: Make collections.abc.Coroutine derived from Awaitable (Merge 3.5)
Yury Selivanov yselivanov@sprymix.com | |
---|---|
date | Fri, 29 May 2015 09:01:47 -0400 |
parents | c9d89d3f3ff1(current diff)968af3838553(diff) |
children | 748c55375225 |
files | Lib/test/test_collections.py |
diffstat | 4 files changed, 67 insertions(+), 40 deletions(-)[+] [-] Doc/library/collections.abc.rst 10 Lib/_collections_abc.py 49 Lib/test/test_asyncio/test_pep492.py 14 Lib/test/test_collections.py 34 |
line wrap: on
line diff
--- a/Doc/library/collections.abc.rst
+++ b/Doc/library/collections.abc.rst
@@ -82,7 +82,7 @@ ABC Inherits from
:class:Set
__iter__
:class:ValuesView
:class:MappingView
__contains__
, __iter__
:class:Awaitable
__await__
-:class:Coroutine
send
, throw
close
+:class:Coroutine
:class:Awaitable
send
, throw
close
:class:AsyncIterable
__aiter__
:class:AsyncIterator
:class:AsyncIterable
__anext__
__aiter__
========================== ====================== ======================= ====================================================
@@ -166,10 +166,10 @@ ABC Inherits from
ABC for coroutine compatible classes that implement a subset of
generator methods defined in :pep:342
, namely:
- :meth:
~generator.send
, :meth:~generator.throw
and - :meth:
~generator.close
methods. All :class:Coroutine
instances - are also instances of :class:
Awaitable
. See also the definition - of :term:
coroutine
.
- :meth:
~generator.send
, :meth:~generator.throw
, - :meth:
~generator.close
methods. :meth:__await__
must also be - implemented. All :class:
Coroutine
instances are also instances of - :class:
Awaitable
. See also the definition of :term:coroutine
. .. versionadded:: 3.5
--- a/Lib/_collections_abc.py +++ b/Lib/_collections_abc.py @@ -75,7 +75,7 @@ class Hashable(metaclass=ABCMeta): return NotImplemented -class _CoroutineMeta(ABCMeta): +class _AwaitableMeta(ABCMeta): def instancecheck(cls, instance): # 0x80 = CO_COROUTINE @@ -92,7 +92,26 @@ class _CoroutineMeta(ABCMeta): return super().instancecheck(instance) -class Coroutine(metaclass=_CoroutineMeta): +class Awaitable(metaclass=_AwaitableMeta): +
- @classmethod
- def subclasshook(cls, C):
if cls is Awaitable:[](#l2.27)
for B in C.__mro__:[](#l2.28)
if "__await__" in B.__dict__:[](#l2.29)
if B.__dict__["__await__"]:[](#l2.30)
return True[](#l2.31)
break[](#l2.32)
return NotImplemented[](#l2.33)
+ + +class Coroutine(Awaitable): slots = () @@ -126,27 +145,19 @@ class Coroutine(metaclass=_CoroutineMeta else: raise RuntimeError("coroutine ignored GeneratorExit") - -class Awaitable(metaclass=_CoroutineMeta): -
- @classmethod def subclasshook(cls, C):
if cls is Awaitable:[](#l2.55)
for B in C.__mro__:[](#l2.56)
if "__await__" in B.__dict__:[](#l2.57)
if B.__dict__["__await__"]:[](#l2.58)
return True[](#l2.59)
break[](#l2.60)
if cls is Coroutine:[](#l2.61)
mro = C.__mro__[](#l2.62)
for method in ('__await__', 'send', 'throw', 'close'):[](#l2.63)
for base in mro:[](#l2.64)
if method in base.__dict__:[](#l2.65)
break[](#l2.66)
else:[](#l2.67)
return NotImplemented[](#l2.68)
return True[](#l2.69) return NotImplemented[](#l2.70)
-Awaitable.register(Coroutine) - class AsyncIterable(metaclass=ABCMeta):
--- a/Lib/test/test_asyncio/test_pep492.py +++ b/Lib/test/test_asyncio/test_pep492.py @@ -97,18 +97,14 @@ class CoroutineTests(BaseTest): finally: f.close() # silence warning
class FakeCoro(collections.abc.Coroutine):[](#l3.7)
# Test that asyncio.iscoroutine() uses collections.abc.Coroutine[](#l3.8)
class FakeCoro:[](#l3.9) def send(self, value): pass[](#l3.10) def throw(self, typ, val=None, tb=None): pass[](#l3.11)
def close(self): pass[](#l3.12)
def __await__(self): yield[](#l3.13)
fc = FakeCoro()[](#l3.15)
try:[](#l3.16)
self.assertTrue(asyncio.iscoroutine(fc))[](#l3.17)
finally:[](#l3.18)
# To make sure that ABCMeta caches are freed[](#l3.19)
# from FakeCoro ASAP.[](#l3.20)
fc = FakeCoro = None[](#l3.21)
support.gc_collect()[](#l3.22)
self.assertTrue(asyncio.iscoroutine(FakeCoro()))[](#l3.23)
--- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -496,6 +496,8 @@ class TestOneTrickPonyABCs(ABCTestCase): return value def throw(self, typ, val=None, tb=None): super().throw(typ, val, tb)
def __await__(self):[](#l4.7)
yield[](#l4.8)
non_samples = [None, int(), gen(), object()] for x in non_samples: @@ -515,13 +517,7 @@ class TestOneTrickPonyABCs(ABCTestCase): self.assertIsInstance(c, Awaitable) c.close() # awoid RuntimeWarning that coro() was not awaited
class CoroLike:[](#l4.16)
def send(self, value):[](#l4.17)
pass[](#l4.18)
def throw(self, typ, val=None, tb=None):[](#l4.19)
pass[](#l4.20)
def close(self):[](#l4.21)
pass[](#l4.22)
class CoroLike: pass[](#l4.23) Coroutine.register(CoroLike)[](#l4.24) self.assertTrue(isinstance(CoroLike(), Awaitable))[](#l4.25) self.assertTrue(issubclass(CoroLike, Awaitable))[](#l4.26)
@@ -548,6 +544,8 @@ class TestOneTrickPonyABCs(ABCTestCase): return value def throw(self, typ, val=None, tb=None): super().throw(typ, val, tb)
def __await__(self):[](#l4.31)
yield[](#l4.32)
non_samples = [None, int(), gen(), object(), Bar()] for x in non_samples: @@ -567,6 +565,28 @@ class TestOneTrickPonyABCs(ABCTestCase): self.assertIsInstance(c, Coroutine) c.close() # awoid RuntimeWarning that coro() was not awaited
class CoroLike:[](#l4.40)
def send(self, value):[](#l4.41)
pass[](#l4.42)
def throw(self, typ, val=None, tb=None):[](#l4.43)
pass[](#l4.44)
def close(self):[](#l4.45)
pass[](#l4.46)
def __await__(self):[](#l4.47)
pass[](#l4.48)
self.assertTrue(isinstance(CoroLike(), Coroutine))[](#l4.49)
self.assertTrue(issubclass(CoroLike, Coroutine))[](#l4.50)
class CoroLike:[](#l4.52)
def send(self, value):[](#l4.53)
pass[](#l4.54)
def close(self):[](#l4.55)
pass[](#l4.56)
def __await__(self):[](#l4.57)
pass[](#l4.58)
self.assertFalse(isinstance(CoroLike(), Coroutine))[](#l4.59)
self.assertFalse(issubclass(CoroLike, Coroutine))[](#l4.60)
+ def test_Hashable(self): # Check some non-hashables non_samples = [bytearray(), list(), set(), dict()]