summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
Diffstat (limited to 'Lib')
-rw-r--r--Lib/lib2to3/Grammar.txt2
-rw-r--r--Lib/lib2to3/tests/test_parser.py18
-rw-r--r--Lib/test/badsyntax_async1.py2
-rw-r--r--Lib/test/badsyntax_async2.py2
-rw-r--r--Lib/test/badsyntax_async3.py2
-rw-r--r--Lib/test/badsyntax_async4.py2
-rw-r--r--Lib/test/badsyntax_async5.py2
-rw-r--r--Lib/test/badsyntax_async7.py2
-rw-r--r--Lib/test/badsyntax_async8.py2
-rw-r--r--Lib/test/test_ast.py35
-rw-r--r--Lib/test/test_coroutines.py324
11 files changed, 330 insertions, 63 deletions
diff --git a/Lib/lib2to3/Grammar.txt b/Lib/lib2to3/Grammar.txt
index abe1268..dcdd02d 100644
--- a/Lib/lib2to3/Grammar.txt
+++ b/Lib/lib2to3/Grammar.txt
@@ -150,7 +150,7 @@ arglist: (argument ',')* (argument [',']
argument: test [comp_for] | test '=' test # Really [keyword '='] test
comp_iter: comp_for | comp_if
-comp_for: 'for' exprlist 'in' testlist_safe [comp_iter]
+comp_for: [ASYNC] 'for' exprlist 'in' testlist_safe [comp_iter]
comp_if: 'if' old_test [comp_iter]
testlist1: test (',' test)*
diff --git a/Lib/lib2to3/tests/test_parser.py b/Lib/lib2to3/tests/test_parser.py
index b378163..7613f53 100644
--- a/Lib/lib2to3/tests/test_parser.py
+++ b/Lib/lib2to3/tests/test_parser.py
@@ -134,6 +134,24 @@ class TestAsyncAwait(GrammarTest):
""")
self.validate("""async def foo():
+ [i async for i in b]
+ """)
+
+ self.validate("""async def foo():
+ {i for i in b
+ async for i in a if await i
+ for b in i}
+ """)
+
+ self.validate("""async def foo():
+ [await i for i in b if await c]
+ """)
+
+ self.validate("""async def foo():
+ [ i for i in b if c]
+ """)
+
+ self.validate("""async def foo():
def foo(): pass
diff --git a/Lib/test/badsyntax_async1.py b/Lib/test/badsyntax_async1.py
deleted file mode 100644
index fb85e29..0000000
--- a/Lib/test/badsyntax_async1.py
+++ /dev/null
@@ -1,2 +0,0 @@
-async def foo(a=await something()):
- pass
diff --git a/Lib/test/badsyntax_async2.py b/Lib/test/badsyntax_async2.py
deleted file mode 100644
index fb85e29..0000000
--- a/Lib/test/badsyntax_async2.py
+++ /dev/null
@@ -1,2 +0,0 @@
-async def foo(a=await something()):
- pass
diff --git a/Lib/test/badsyntax_async3.py b/Lib/test/badsyntax_async3.py
deleted file mode 100644
index dde1bc5..0000000
--- a/Lib/test/badsyntax_async3.py
+++ /dev/null
@@ -1,2 +0,0 @@
-async def foo():
- [i async for i in els]
diff --git a/Lib/test/badsyntax_async4.py b/Lib/test/badsyntax_async4.py
deleted file mode 100644
index d033b28..0000000
--- a/Lib/test/badsyntax_async4.py
+++ /dev/null
@@ -1,2 +0,0 @@
-async def foo():
- await
diff --git a/Lib/test/badsyntax_async5.py b/Lib/test/badsyntax_async5.py
deleted file mode 100644
index 9d19af6..0000000
--- a/Lib/test/badsyntax_async5.py
+++ /dev/null
@@ -1,2 +0,0 @@
-def foo():
- await something()
diff --git a/Lib/test/badsyntax_async7.py b/Lib/test/badsyntax_async7.py
deleted file mode 100644
index 51e4bf9..0000000
--- a/Lib/test/badsyntax_async7.py
+++ /dev/null
@@ -1,2 +0,0 @@
-async def foo():
- yield from []
diff --git a/Lib/test/badsyntax_async8.py b/Lib/test/badsyntax_async8.py
deleted file mode 100644
index 3c636f9..0000000
--- a/Lib/test/badsyntax_async8.py
+++ /dev/null
@@ -1,2 +0,0 @@
-async def foo():
- await await fut
diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py
index e032f6d..8c62408 100644
--- a/Lib/test/test_ast.py
+++ b/Lib/test/test_ast.py
@@ -116,6 +116,8 @@ exec_tests = [
# PEP 448: Additional Unpacking Generalizations
"{**{1:2}, 2:3}",
"{*{1, 2}, 3}",
+ # Asynchronous comprehensions
+ "async def f():\n [i async for b in c]",
]
# These are compiled through "single"
@@ -809,21 +811,21 @@ class ASTValidatorTests(unittest.TestCase):
def _check_comprehension(self, fac):
self.expr(fac([]), "comprehension with no generators")
g = ast.comprehension(ast.Name("x", ast.Load()),
- ast.Name("x", ast.Load()), [])
+ ast.Name("x", ast.Load()), [], 0)
self.expr(fac([g]), "must have Store context")
g = ast.comprehension(ast.Name("x", ast.Store()),
- ast.Name("x", ast.Store()), [])
+ ast.Name("x", ast.Store()), [], 0)
self.expr(fac([g]), "must have Load context")
x = ast.Name("x", ast.Store())
y = ast.Name("y", ast.Load())
- g = ast.comprehension(x, y, [None])
+ g = ast.comprehension(x, y, [None], 0)
self.expr(fac([g]), "None disallowed")
- g = ast.comprehension(x, y, [ast.Name("x", ast.Store())])
+ g = ast.comprehension(x, y, [ast.Name("x", ast.Store())], 0)
self.expr(fac([g]), "must have Load context")
def _simple_comp(self, fac):
g = ast.comprehension(ast.Name("x", ast.Store()),
- ast.Name("x", ast.Load()), [])
+ ast.Name("x", ast.Load()), [], 0)
self.expr(fac(ast.Name("x", ast.Store()), [g]),
"must have Load context")
def wrap(gens):
@@ -841,7 +843,7 @@ class ASTValidatorTests(unittest.TestCase):
def test_dictcomp(self):
g = ast.comprehension(ast.Name("y", ast.Store()),
- ast.Name("p", ast.Load()), [])
+ ast.Name("p", ast.Load()), [], 0)
c = ast.DictComp(ast.Name("x", ast.Store()),
ast.Name("y", ast.Load()), [g])
self.expr(c, "must have Load context")
@@ -1111,19 +1113,20 @@ exec_results = [
('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Break', (1, 11))], [])]),
('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Continue', (1, 11))], [])]),
('Module', [('For', (1, 0), ('Tuple', (1, 4), [('Name', (1, 4), 'a', ('Store',)), ('Name', (1, 6), 'b', ('Store',))], ('Store',)), ('Name', (1, 11), 'c', ('Load',)), [('Pass', (1, 14))], [])]),
-('Module', [('Expr', (1, 0), ('ListComp', (1, 1), ('Tuple', (1, 2), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [])]))]),
-('Module', [('Expr', (1, 0), ('GeneratorExp', (1, 1), ('Tuple', (1, 2), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [])]))]),
-('Module', [('Expr', (1, 0), ('GeneratorExp', (1, 1), ('Tuple', (1, 2), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 12), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [])]))]),
-('Module', [('Expr', (1, 0), ('GeneratorExp', (2, 4), ('Tuple', (3, 4), [('Name', (3, 4), 'Aa', ('Load',)), ('Name', (5, 7), 'Bb', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (8, 4), [('Name', (8, 4), 'Aa', ('Store',)), ('Name', (10, 4), 'Bb', ('Store',))], ('Store',)), ('Name', (10, 10), 'Cc', ('Load',)), [])]))]),
-('Module', [('Expr', (1, 0), ('DictComp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Name', (1, 11), 'w', ('Store',)), ('Name', (1, 16), 'x', ('Load',)), []), ('comprehension', ('Name', (1, 22), 'm', ('Store',)), ('Name', (1, 27), 'p', ('Load',)), [('Name', (1, 32), 'g', ('Load',))])]))]),
-('Module', [('Expr', (1, 0), ('DictComp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'v', ('Store',)), ('Name', (1, 13), 'w', ('Store',))], ('Store',)), ('Name', (1, 18), 'x', ('Load',)), [])]))]),
-('Module', [('Expr', (1, 0), ('SetComp', (1, 0), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 12), 'x', ('Load',)), [('Name', (1, 17), 'g', ('Load',))])]))]),
-('Module', [('Expr', (1, 0), ('SetComp', (1, 0), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Tuple', (1, 7), [('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 9), 'm', ('Store',))], ('Store',)), ('Name', (1, 14), 'x', ('Load',)), [])]))]),
+('Module', [('Expr', (1, 0), ('ListComp', (1, 1), ('Tuple', (1, 2), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [], 0)]))]),
+('Module', [('Expr', (1, 0), ('GeneratorExp', (1, 1), ('Tuple', (1, 2), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [], 0)]))]),
+('Module', [('Expr', (1, 0), ('GeneratorExp', (1, 1), ('Tuple', (1, 2), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 12), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [], 0)]))]),
+('Module', [('Expr', (1, 0), ('GeneratorExp', (2, 4), ('Tuple', (3, 4), [('Name', (3, 4), 'Aa', ('Load',)), ('Name', (5, 7), 'Bb', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (8, 4), [('Name', (8, 4), 'Aa', ('Store',)), ('Name', (10, 4), 'Bb', ('Store',))], ('Store',)), ('Name', (10, 10), 'Cc', ('Load',)), [], 0)]))]),
+('Module', [('Expr', (1, 0), ('DictComp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Name', (1, 11), 'w', ('Store',)), ('Name', (1, 16), 'x', ('Load',)), [], 0), ('comprehension', ('Name', (1, 22), 'm', ('Store',)), ('Name', (1, 27), 'p', ('Load',)), [('Name', (1, 32), 'g', ('Load',))], 0)]))]),
+('Module', [('Expr', (1, 0), ('DictComp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'v', ('Store',)), ('Name', (1, 13), 'w', ('Store',))], ('Store',)), ('Name', (1, 18), 'x', ('Load',)), [], 0)]))]),
+('Module', [('Expr', (1, 0), ('SetComp', (1, 0), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 12), 'x', ('Load',)), [('Name', (1, 17), 'g', ('Load',))], 0)]))]),
+('Module', [('Expr', (1, 0), ('SetComp', (1, 0), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Tuple', (1, 7), [('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 9), 'm', ('Store',))], ('Store',)), ('Name', (1, 14), 'x', ('Load',)), [], 0)]))]),
('Module', [('AsyncFunctionDef', (1, 6), 'f', ('arguments', [], None, [], [], None, []), [('Expr', (2, 1), ('Await', (2, 1), ('Call', (2, 7), ('Name', (2, 7), 'something', ('Load',)), [], [])))], [], None)]),
('Module', [('AsyncFunctionDef', (1, 6), 'f', ('arguments', [], None, [], [], None, []), [('AsyncFor', (2, 7), ('Name', (2, 11), 'e', ('Store',)), ('Name', (2, 16), 'i', ('Load',)), [('Expr', (2, 19), ('Num', (2, 19), 1))], [('Expr', (3, 7), ('Num', (3, 7), 2))])], [], None)]),
('Module', [('AsyncFunctionDef', (1, 6), 'f', ('arguments', [], None, [], [], None, []), [('AsyncWith', (2, 7), [('withitem', ('Name', (2, 12), 'a', ('Load',)), ('Name', (2, 17), 'b', ('Store',)))], [('Expr', (2, 20), ('Num', (2, 20), 1))])], [], None)]),
('Module', [('Expr', (1, 0), ('Dict', (1, 0), [None, ('Num', (1, 10), 2)], [('Dict', (1, 3), [('Num', (1, 4), 1)], [('Num', (1, 6), 2)]), ('Num', (1, 12), 3)]))]),
('Module', [('Expr', (1, 0), ('Set', (1, 0), [('Starred', (1, 1), ('Set', (1, 2), [('Num', (1, 3), 1), ('Num', (1, 6), 2)]), ('Load',)), ('Num', (1, 10), 3)]))]),
+('Module', [('AsyncFunctionDef', (1, 6), 'f', ('arguments', [], None, [], [], None, []), [('Expr', (2, 1), ('ListComp', (2, 2), ('Name', (2, 2), 'i', ('Load',)), [('comprehension', ('Name', (2, 14), 'b', ('Store',)), ('Name', (2, 19), 'c', ('Load',)), [], 1)]))], [], None)]),
]
single_results = [
('Interactive', [('Expr', (1, 0), ('BinOp', (1, 0), ('Num', (1, 0), 1), ('Add',), ('Num', (1, 2), 2)))]),
@@ -1138,8 +1141,8 @@ eval_results = [
('Expression', ('Dict', (1, 0), [], [])),
('Expression', ('Set', (1, 0), [('NameConstant', (1, 1), None)])),
('Expression', ('Dict', (1, 0), [('Num', (2, 6), 1)], [('Num', (4, 10), 2)])),
-('Expression', ('ListComp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))])])),
-('Expression', ('GeneratorExp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))])])),
+('Expression', ('ListComp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))], 0)])),
+('Expression', ('GeneratorExp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))], 0)])),
('Expression', ('Compare', (1, 0), ('Num', (1, 0), 1), [('Lt',), ('Lt',)], [('Num', (1, 4), 2), ('Num', (1, 8), 3)])),
('Expression', ('Call', (1, 0), ('Name', (1, 0), 'f', ('Load',)), [('Num', (1, 2), 1), ('Num', (1, 4), 2), ('Starred', (1, 10), ('Name', (1, 11), 'd', ('Load',)), ('Load',))], [('keyword', 'c', ('Num', (1, 8), 3)), ('keyword', None, ('Name', (1, 15), 'e', ('Load',)))])),
('Expression', ('Num', (1, 0), 10)),
diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py
index fee9ae3..154ce7f 100644
--- a/Lib/test/test_coroutines.py
+++ b/Lib/test/test_coroutines.py
@@ -69,49 +69,130 @@ def silence_coro_gc():
class AsyncBadSyntaxTest(unittest.TestCase):
def test_badsyntax_1(self):
- with self.assertRaisesRegex(SyntaxError, "'await' outside"):
- import test.badsyntax_async1
+ samples = [
+ """def foo():
+ await something()
+ """,
- def test_badsyntax_2(self):
- with self.assertRaisesRegex(SyntaxError, "'await' outside"):
- import test.badsyntax_async2
+ """await something()""",
- def test_badsyntax_3(self):
- with self.assertRaisesRegex(SyntaxError, 'invalid syntax'):
- import test.badsyntax_async3
+ """async def foo():
+ yield from []
+ """,
- def test_badsyntax_4(self):
- with self.assertRaisesRegex(SyntaxError, 'invalid syntax'):
- import test.badsyntax_async4
+ """async def foo():
+ await await fut
+ """,
- def test_badsyntax_5(self):
- with self.assertRaisesRegex(SyntaxError, 'invalid syntax'):
- import test.badsyntax_async5
+ """async def foo(a=await something()):
+ pass
+ """,
- def test_badsyntax_7(self):
- with self.assertRaisesRegex(
- SyntaxError, "'yield from' inside async function"):
+ """async def foo(a:await something()):
+ pass
+ """,
+
+ """async def foo():
+ def bar():
+ [i async for i in els]
+ """,
- import test.badsyntax_async7
+ """async def foo():
+ def bar():
+ [await i for i in els]
+ """,
- def test_badsyntax_8(self):
- with self.assertRaisesRegex(SyntaxError, 'invalid syntax'):
- import test.badsyntax_async8
+ """async def foo():
+ def bar():
+ [i for i in els
+ async for b in els]
+ """,
- def test_badsyntax_9(self):
- ns = {}
- for comp in {'(await a for a in b)',
- '[await a for a in b]',
- '{await a for a in b}',
- '{await a: c for a in b}'}:
+ """async def foo():
+ def bar():
+ [i for i in els
+ for c in b
+ async for b in els]
+ """,
- with self.assertRaisesRegex(SyntaxError, 'await.*in comprehen'):
- exec('async def f():\n\t{}'.format(comp), ns, ns)
+ """async def foo():
+ def bar():
+ [i for i in els
+ async for b in els
+ for c in b]
+ """,
- def test_badsyntax_10(self):
- # Tests for issue 24619
+ """async def foo():
+ def bar():
+ [i for i in els
+ for b in await els]
+ """,
+
+ """async def foo():
+ def bar():
+ [i for i in els
+ for b in els
+ if await b]
+ """,
+
+ """async def foo():
+ def bar():
+ [i for i in await els]
+ """,
+
+ """async def foo():
+ def bar():
+ [i for i in els if await i]
+ """,
+
+ """def bar():
+ [i async for i in els]
+ """,
+
+ """def bar():
+ [await i for i in els]
+ """,
+
+ """def bar():
+ [i for i in els
+ async for b in els]
+ """,
+
+ """def bar():
+ [i for i in els
+ for c in b
+ async for b in els]
+ """,
+
+ """def bar():
+ [i for i in els
+ async for b in els
+ for c in b]
+ """,
+
+ """def bar():
+ [i for i in els
+ for b in await els]
+ """,
+
+ """def bar():
+ [i for i in els
+ for b in els
+ if await b]
+ """,
+
+ """def bar():
+ [i for i in await els]
+ """,
+
+ """def bar():
+ [i for i in els if await i]
+ """,
+
+ """async def foo():
+ await
+ """,
- samples = [
"""async def foo():
def bar(): pass
await = 1
@@ -1531,6 +1612,185 @@ class CoroutineTest(unittest.TestCase):
warnings.simplefilter("error")
run_async(foo())
+ def test_comp_1(self):
+ async def f(i):
+ return i
+
+ async def run_list():
+ return [await c for c in [f(1), f(41)]]
+
+ async def run_set():
+ return {await c for c in [f(1), f(41)]}
+
+ async def run_dict1():
+ return {await c: 'a' for c in [f(1), f(41)]}
+
+ async def run_dict2():
+ return {i: await c for i, c in enumerate([f(1), f(41)])}
+
+ self.assertEqual(run_async(run_list()), ([], [1, 41]))
+ self.assertEqual(run_async(run_set()), ([], {1, 41}))
+ self.assertEqual(run_async(run_dict1()), ([], {1: 'a', 41: 'a'}))
+ self.assertEqual(run_async(run_dict2()), ([], {0: 1, 1: 41}))
+
+ def test_comp_2(self):
+ async def f(i):
+ return i
+
+ async def run_list():
+ return [s for c in [f(''), f('abc'), f(''), f(['de', 'fg'])]
+ for s in await c]
+
+ self.assertEqual(
+ run_async(run_list()),
+ ([], ['a', 'b', 'c', 'de', 'fg']))
+
+ async def run_set():
+ return {d
+ for c in [f([f([10, 30]),
+ f([20])])]
+ for s in await c
+ for d in await s}
+
+ self.assertEqual(
+ run_async(run_set()),
+ ([], {10, 20, 30}))
+
+ async def run_set2():
+ return {await s
+ for c in [f([f(10), f(20)])]
+ for s in await c}
+
+ self.assertEqual(
+ run_async(run_set2()),
+ ([], {10, 20}))
+
+ def test_comp_3(self):
+ async def f(it):
+ for i in it:
+ yield i
+
+ async def run_list():
+ return [i + 1 async for i in f([10, 20])]
+ self.assertEqual(
+ run_async(run_list()),
+ ([], [11, 21]))
+
+ async def run_set():
+ return {i + 1 async for i in f([10, 20])}
+ self.assertEqual(
+ run_async(run_set()),
+ ([], {11, 21}))
+
+ async def run_dict():
+ return {i + 1: i + 2 async for i in f([10, 20])}
+ self.assertEqual(
+ run_async(run_dict()),
+ ([], {11: 12, 21: 22}))
+
+ async def run_gen():
+ gen = (i + 1 async for i in f([10, 20]))
+ return [g + 100 async for g in gen]
+ self.assertEqual(
+ run_async(run_gen()),
+ ([], [111, 121]))
+
+ def test_comp_4(self):
+ async def f(it):
+ for i in it:
+ yield i
+
+ async def run_list():
+ return [i + 1 async for i in f([10, 20]) if i > 10]
+ self.assertEqual(
+ run_async(run_list()),
+ ([], [21]))
+
+ async def run_set():
+ return {i + 1 async for i in f([10, 20]) if i > 10}
+ self.assertEqual(
+ run_async(run_set()),
+ ([], {21}))
+
+ async def run_dict():
+ return {i + 1: i + 2 async for i in f([10, 20]) if i > 10}
+ self.assertEqual(
+ run_async(run_dict()),
+ ([], {21: 22}))
+
+ async def run_gen():
+ gen = (i + 1 async for i in f([10, 20]) if i > 10)
+ return [g + 100 async for g in gen]
+ self.assertEqual(
+ run_async(run_gen()),
+ ([], [121]))
+
+ def test_comp_5(self):
+ async def f(it):
+ for i in it:
+ yield i
+
+ async def run_list():
+ return [i + 1 for pair in ([10, 20], [30, 40]) if pair[0] > 10
+ async for i in f(pair) if i > 30]
+ self.assertEqual(
+ run_async(run_list()),
+ ([], [41]))
+
+ def test_comp_6(self):
+ async def f(it):
+ for i in it:
+ yield i
+
+ async def run_list():
+ return [i + 1 async for seq in f([(10, 20), (30,)])
+ for i in seq]
+
+ self.assertEqual(
+ run_async(run_list()),
+ ([], [11, 21, 31]))
+
+ def test_comp_7(self):
+ async def f():
+ yield 1
+ yield 2
+ raise Exception('aaa')
+
+ async def run_list():
+ return [i async for i in f()]
+
+ with self.assertRaisesRegex(Exception, 'aaa'):
+ run_async(run_list())
+
+ def test_comp_8(self):
+ async def f():
+ return [i for i in [1, 2, 3]]
+
+ self.assertEqual(
+ run_async(f()),
+ ([], [1, 2, 3]))
+
+ def test_comp_9(self):
+ async def gen():
+ yield 1
+ yield 2
+ async def f():
+ l = [i async for i in gen()]
+ return [i for i in l]
+
+ self.assertEqual(
+ run_async(f()),
+ ([], [1, 2]))
+
+ def test_comp_10(self):
+ async def f():
+ xx = {i for i in [1, 2, 3]}
+ return {x: x for x in xx}
+
+ self.assertEqual(
+ run_async(f()),
+ ([], {1: 1, 2: 2, 3: 3}))
+
def test_copy(self):
async def func(): pass
coro = func()