summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
Diffstat (limited to 'Lib')
-rw-r--r--Lib/_collections_abc.py4
-rw-r--r--Lib/asyncio/compat.py1
-rw-r--r--Lib/asyncio/streams.py6
-rw-r--r--Lib/test/test_coroutines.py98
-rw-r--r--Lib/test/test_grammar.py2
5 files changed, 88 insertions, 23 deletions
diff --git a/Lib/_collections_abc.py b/Lib/_collections_abc.py
index f89bb6f..fc9c9f1 100644
--- a/Lib/_collections_abc.py
+++ b/Lib/_collections_abc.py
@@ -156,7 +156,7 @@ class AsyncIterable(metaclass=ABCMeta):
__slots__ = ()
@abstractmethod
- async def __aiter__(self):
+ def __aiter__(self):
return AsyncIterator()
@classmethod
@@ -176,7 +176,7 @@ class AsyncIterator(AsyncIterable):
"""Return the next item or raise StopAsyncIteration when exhausted."""
raise StopAsyncIteration
- async def __aiter__(self):
+ def __aiter__(self):
return self
@classmethod
diff --git a/Lib/asyncio/compat.py b/Lib/asyncio/compat.py
index 660b7e7..4790bb4 100644
--- a/Lib/asyncio/compat.py
+++ b/Lib/asyncio/compat.py
@@ -4,6 +4,7 @@ import sys
PY34 = sys.version_info >= (3, 4)
PY35 = sys.version_info >= (3, 5)
+PY352 = sys.version_info >= (3, 5, 2)
def flatten_list_bytes(list_of_data):
diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py
index 6f465af..c88a87c 100644
--- a/Lib/asyncio/streams.py
+++ b/Lib/asyncio/streams.py
@@ -689,3 +689,9 @@ class StreamReader:
if val == b'':
raise StopAsyncIteration
return val
+
+ if compat.PY352:
+ # In Python 3.5.2 and greater, __aiter__ should return
+ # the asynchronous iterator directly.
+ def __aiter__(self):
+ return self
diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py
index 187348d..4f725ae 100644
--- a/Lib/test/test_coroutines.py
+++ b/Lib/test/test_coroutines.py
@@ -1255,8 +1255,9 @@ class CoroutineTest(unittest.TestCase):
buffer = []
async def test1():
- async for i1, i2 in AsyncIter():
- buffer.append(i1 + i2)
+ with self.assertWarnsRegex(PendingDeprecationWarning, "legacy"):
+ async for i1, i2 in AsyncIter():
+ buffer.append(i1 + i2)
yielded, _ = run_async(test1())
# Make sure that __aiter__ was called only once
@@ -1268,12 +1269,13 @@ class CoroutineTest(unittest.TestCase):
buffer = []
async def test2():
nonlocal buffer
- async for i in AsyncIter():
- buffer.append(i[0])
- if i[0] == 20:
- break
- else:
- buffer.append('what?')
+ with self.assertWarnsRegex(PendingDeprecationWarning, "legacy"):
+ async for i in AsyncIter():
+ buffer.append(i[0])
+ if i[0] == 20:
+ break
+ else:
+ buffer.append('what?')
buffer.append('end')
yielded, _ = run_async(test2())
@@ -1286,12 +1288,13 @@ class CoroutineTest(unittest.TestCase):
buffer = []
async def test3():
nonlocal buffer
- async for i in AsyncIter():
- if i[0] > 20:
- continue
- buffer.append(i[0])
- else:
- buffer.append('what?')
+ with self.assertWarnsRegex(PendingDeprecationWarning, "legacy"):
+ async for i in AsyncIter():
+ if i[0] > 20:
+ continue
+ buffer.append(i[0])
+ else:
+ buffer.append('what?')
buffer.append('end')
yielded, _ = run_async(test3())
@@ -1338,7 +1341,7 @@ class CoroutineTest(unittest.TestCase):
def test_for_4(self):
class I:
- async def __aiter__(self):
+ def __aiter__(self):
return self
def __anext__(self):
@@ -1368,8 +1371,9 @@ class CoroutineTest(unittest.TestCase):
return 123
async def foo():
- async for i in I():
- print('never going to happen')
+ with self.assertWarnsRegex(PendingDeprecationWarning, "legacy"):
+ async for i in I():
+ print('never going to happen')
with self.assertRaisesRegex(
TypeError,
@@ -1393,7 +1397,7 @@ class CoroutineTest(unittest.TestCase):
def __init__(self):
self.i = 0
- async def __aiter__(self):
+ def __aiter__(self):
return self
async def __anext__(self):
@@ -1417,7 +1421,11 @@ class CoroutineTest(unittest.TestCase):
I += 1
I += 1000
- run_async(main())
+ with warnings.catch_warnings():
+ warnings.simplefilter("error")
+ # Test that __aiter__ that returns an asyncronous iterator
+ # directly does not throw any warnings.
+ run_async(main())
self.assertEqual(I, 111011)
self.assertEqual(sys.getrefcount(manager), mrefs_before)
@@ -1472,13 +1480,63 @@ class CoroutineTest(unittest.TestCase):
1/0
async def foo():
nonlocal CNT
+ with self.assertWarnsRegex(PendingDeprecationWarning, "legacy"):
+ async for i in AI():
+ CNT += 1
+ CNT += 10
+ with self.assertRaises(ZeroDivisionError):
+ run_async(foo())
+ self.assertEqual(CNT, 0)
+
+ def test_for_8(self):
+ CNT = 0
+ class AI:
+ def __aiter__(self):
+ 1/0
+ async def foo():
+ nonlocal CNT
async for i in AI():
CNT += 1
CNT += 10
with self.assertRaises(ZeroDivisionError):
- run_async(foo())
+ with warnings.catch_warnings():
+ warnings.simplefilter("error")
+ # Test that if __aiter__ raises an exception it propagates
+ # without any kind of warning.
+ run_async(foo())
self.assertEqual(CNT, 0)
+ def test_for_9(self):
+ # Test that PendingDeprecationWarning can safely be converted into
+ # an exception (__aiter__ should not have a chance to raise
+ # a ZeroDivisionError.)
+ class AI:
+ async def __aiter__(self):
+ 1/0
+ async def foo():
+ async for i in AI():
+ pass
+
+ with self.assertRaises(PendingDeprecationWarning):
+ with warnings.catch_warnings():
+ warnings.simplefilter("error")
+ run_async(foo())
+
+ def test_for_10(self):
+ # Test that PendingDeprecationWarning can safely be converted into
+ # an exception.
+ class AI:
+ async def __aiter__(self):
+ pass
+ async def foo():
+ async for i in AI():
+ pass
+
+ with self.assertRaises(PendingDeprecationWarning):
+ with warnings.catch_warnings():
+ warnings.simplefilter("error")
+ run_async(foo())
+
def test_copy(self):
async def func(): pass
coro = func()
diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py
index d68cc7d..154e3b6 100644
--- a/Lib/test/test_grammar.py
+++ b/Lib/test/test_grammar.py
@@ -1076,7 +1076,7 @@ class GrammarTests(unittest.TestCase):
class Done(Exception): pass
class AIter:
- async def __aiter__(self):
+ def __aiter__(self):
return self
async def __anext__(self):
raise StopAsyncIteration