Skip to content

Commit f2dbc91

Browse files
jeplerdpgeorge
authored andcommitted
py/compile: Raise an error on async with/for outside an async function.
A simple reproducer is: async for x in (): x Before this change, it would cause an assertion error in mpy-cross and micropython-coverage.
1 parent a60ad33 commit f2dbc91

File tree

3 files changed

+37
-6
lines changed

3 files changed

+37
-6
lines changed

py/compile.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1970,13 +1970,23 @@ STATIC void compile_async_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
19701970
compile_funcdef(comp, pns0);
19711971
scope_t *fscope = (scope_t *)pns0->nodes[4];
19721972
fscope->scope_flags |= MP_SCOPE_FLAG_GENERATOR;
1973-
} else if (MP_PARSE_NODE_STRUCT_KIND(pns0) == PN_for_stmt) {
1974-
// async for
1975-
compile_async_for_stmt(comp, pns0);
19761973
} else {
1977-
// async with
1978-
assert(MP_PARSE_NODE_STRUCT_KIND(pns0) == PN_with_stmt);
1979-
compile_async_with_stmt(comp, pns0);
1974+
// async for/with; first verify the scope is a generator
1975+
int scope_flags = comp->scope_cur->scope_flags;
1976+
if (!(scope_flags & MP_SCOPE_FLAG_GENERATOR)) {
1977+
compile_syntax_error(comp, (mp_parse_node_t)pns0,
1978+
MP_ERROR_TEXT("async for/with outside async function"));
1979+
return;
1980+
}
1981+
1982+
if (MP_PARSE_NODE_STRUCT_KIND(pns0) == PN_for_stmt) {
1983+
// async for
1984+
compile_async_for_stmt(comp, pns0);
1985+
} else {
1986+
// async with
1987+
assert(MP_PARSE_NODE_STRUCT_KIND(pns0) == PN_with_stmt);
1988+
compile_async_with_stmt(comp, pns0);
1989+
}
19801990
}
19811991
}
19821992
#endif

tests/basics/async_syntaxerror.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# test syntax errors using async
2+
3+
try:
4+
exec
5+
except NameError:
6+
print("SKIP")
7+
raise SystemExit
8+
9+
10+
def test_syntax(code):
11+
try:
12+
exec(code)
13+
print("no SyntaxError")
14+
except SyntaxError:
15+
print("SyntaxError")
16+
17+
18+
test_syntax("async for x in (): x")
19+
test_syntax("async with x: x")

tests/basics/async_syntaxerror.py.exp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
SyntaxError
2+
SyntaxError

0 commit comments

Comments
 (0)