Skip to content

Commit 52882e4

Browse files
committed
more tests
1 parent 7b80a92 commit 52882e4

2 files changed

Lines changed: 57 additions & 1 deletion

File tree

Lib/test/test_builtin.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,7 @@ async def sleep(delay, result=None):
545545
'''a = [await sleep(0, 1) for _ in [0]][0]''',
546546
'''a = {await sleep(0, 1) for _ in [0]}.pop()''',
547547
'''a = {0: await sleep(0, 1) for _ in [0]}[0]''',
548+
'''a = (lambda x=[await sleep(0, 1) for _ in [0]]: x)()[0]''',
548549
# gh-121637: Make sure we correctly handle the case where the
549550
# async code is optimized away
550551
'''assert not await sleep(0); a = 1''',
@@ -624,6 +625,15 @@ async def __aexit__(self, *exc_info):
624625
class C:
625626
[await x for x in y]
626627
''',
628+
'''lambda: [await x for x in y]''',
629+
'''class C:
630+
def f(self, x=[await y for y in z]):
631+
pass
632+
''',
633+
'''type T = [await x for x in y]''',
634+
'''async def f[T=[await x for x in y]]():
635+
pass
636+
''',
627637
]
628638
for mode, code_sample in product(modes, code_samples):
629639
source = dedent(code_sample)

Lib/test/test_coroutines.py

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import ast
12
import contextlib
23
import copy
34
import inspect
@@ -418,17 +419,26 @@ def test_async_comprehension_scope(self):
418419
"async def f():\n {x async for x in y}",
419420
"async def f():\n {k: x async for k, x in y}",
420421
"async def f():\n [[await x for x in y] for y in z]",
422+
# Defaults and bases are evaluated in the enclosing scope.
423+
"async def outer():\n async def f(x=[await y for y in z]): pass",
424+
"async def f():\n class C([await x for x in y]): pass",
421425
]
422426
for code in allowed:
423427
with self.subTest(code=code):
424428
compile(code, "<test>", "exec")
425429

426430
# Generator expressions with await are async genexps and may appear
427-
# outside async functions.
431+
# outside async functions. A listcomp nested in a genexp is also
432+
# allowed (the genexp becomes an async generator).
428433
for code in [
429434
"(await x for x in y)",
430435
"def f():\n (await x for x in y)",
431436
"class C:\n (await x for x in y)",
437+
"lambda: (await x for x in y)",
438+
"([await x for x in y] for y in z)",
439+
"def f():\n ([await x for x in y] for y in z)",
440+
"class C:\n ([await x for x in y] for y in z)",
441+
"async def f():\n ([await x for x in y] for y in z)",
432442
]:
433443
with self.subTest(code=code):
434444
compile(code, "<test>", "exec")
@@ -453,6 +463,22 @@ def test_async_comprehension_scope(self):
453463
"class C:\n [[await x for x in y] for y in z]",
454464
"async def f():\n class C:\n x = [await y for y in z]",
455465
"async def f():\n class C:\n x = [y async for y in z]",
466+
# Lambdas are never async, even inside async def.
467+
"lambda: [await x for x in y]",
468+
"async def f():\n lambda: [await x for x in y]",
469+
"class C:\n f = lambda: [await x for x in y]",
470+
# Defaults and bases run in the enclosing scope.
471+
"async def f(x=[await y for y in z]): pass",
472+
"def f(x=[await y for y in z]): pass",
473+
"class C:\n def f(self, x=[await y for y in z]): pass",
474+
"class C([await x for x in y]): pass",
475+
# Type aliases and type-parameter scopes.
476+
"type T = [await x for x in y]",
477+
"type T = [x async for x in y]",
478+
"def f[T=[await x for x in y]](): pass",
479+
"def f[T: [await x for x in y]](): pass",
480+
"async def f[T=[await x for x in y]](): pass",
481+
"async def f(x: [await y for y in z]): pass",
456482
]
457483
for code in invalid:
458484
with self.subTest(code=code):
@@ -465,6 +491,26 @@ def test_async_comprehension_scope(self):
465491
support.check_syntax_error(
466492
self, "def f():\n await x", "'await' outside async function")
467493

494+
flags = ast.PyCF_ALLOW_TOP_LEVEL_AWAIT
495+
for code in [
496+
"[await x for x in y]",
497+
"async def f(x=[await y for y in z]): pass",
498+
"class C([await x for x in y]): pass",
499+
"f'{[await x for x in y]}'",
500+
]:
501+
with self.subTest(code=code, tla=True):
502+
compile(code, "<test>", "exec", flags=flags)
503+
still_invalid = [
504+
"lambda: [await x for x in y]",
505+
"class C:\n def f(self, x=[await y for y in z]): pass",
506+
"type T = [await x for x in y]",
507+
"async def f[T=[await x for x in y]](): pass",
508+
]
509+
for code in still_invalid:
510+
with self.subTest(code=code, tla=True):
511+
with self.assertRaisesRegex(SyntaxError, err):
512+
compile(code, "<test>", "exec", flags=flags)
513+
468514
def test_badsyntax_2(self):
469515
samples = [
470516
"""def foo():

0 commit comments

Comments
 (0)